/ / Uzyskaj wartość z elementu XML za pomocą analizatora składni XML i przypisz go do zmiennej - xml, shell, xslt

Uzyskaj wartość z elementu XML za pomocą analizatora składni XML i przypisz go do zmiennej - xml, shell, xslt

Mam następujący XML:

        <?xml version="1.0" encoding="utf-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>BundleResourceDeploy</groupId>
<artifactId>Project3</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>sbar</packaging>
<description></description>
</project>

Mam również następujący arkusz stylów XSLT:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://maven.apache.org/POM/4.0.0" exclude-result-prefixes="ns">

<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="ns:project">


<xsl:element name="ns:groupId">
<xsl:value-of select="ns:groupId"/>
</xsl:element>

<xsl:element name="ns:artifactId">
<xsl:value-of select="ns:artifactId"/>
</xsl:element>

<xsl:element name="ns:version">
<xsl:value-of select="ns:version"/>
</xsl:element>

<xsl:element name="ns:packaging">
<xsl:value-of select="ns:packaging"/>
</xsl:element>

</xsl:template>
</xsl:stylesheet>

Wykonywanie polecenia: xsltproc "stylesheet" "xml_file"> output.xml

Dane wyjściowe (zawartość pliku output.xml) to:

<ns:groupId xmlns:ns="http://maven.apache.org/POM/4.0.0">BundleResourceDeploy</ns:groupId><ns:artifactId xmlns:ns="http://maven.apache.org/POM/4.0.0">Project2</ns:artifactId><ns:version xmlns:ns="http://maven.apache.org/POM/4.0.0">1.0-SNAPSHOT</ns:version><ns:packaging xmlns:ns="http://maven.apache.org/POM/4.0.0">sbar</ns:packaging>

Co chcę osiągnąć to: W skrypcie powłoki chcę uzyskać wartość elementu "groupId", który byłby "BundleResourceDeploy" i przypisać go do zmiennej.

Czy możesz mi pomóc w sposób, w jaki sposób to osiągnąć?

Odpowiedzi:

0 dla odpowiedzi № 1

Osobiście użyłbym XMLStarlet:

#!/bin/bash
#      ^^^^-- NOT /bin/sh; process substitution is an extension in ksh and bash
#             $"" literal syntax is an extension as well, likewise read -d

IFS=$"n" read -r -d "" groupId artifactId version packaging < <(
xmlstarlet sel 
-N ns="http://maven.apache.org/POM/4.0.0" 
-t -m /ns:project 
-v ns:groupId -n 
-v ns:artifactId -n 
-v ns:version -n 
-v ns:packaging -n 
<pom.xml && printf ""
)

echo "pom.xml is for $groupId/$artifactId, version $version, with packaging $packaging"

Jednak, co xmlstarlet Polecenie w tym skrypcie faktycznie jest w pełni równoznaczne z nieco innym szablonem XSLT, który możesz poprosić XMLStarlet, aby wygenerował dla ciebie, przekazując -C argument:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://maven.apache.org/POM/4.0.0" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="/ns:project">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="ns:groupId"/>
</xsl:call-template>
<xsl:value-of select=""&#10;""/>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="ns:artifactId"/>
</xsl:call-template>
<xsl:value-of select=""&#10;""/>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="ns:version"/>
</xsl:call-template>
<xsl:value-of select=""&#10;""/>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="ns:packaging"/>
</xsl:call-template>
<xsl:value-of select=""&#10;""/>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()&gt;1]">
<xsl:value-of select=""&#10;""/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Zwróć uwagę, że nie tworzymy elementów w naszymtu wyjściowo, ale raczej generując strumień tekstowy ograniczony przez znaki nowej linii. (Będziemy musieli dostosować nasze podejście, jeśli w naszych wartościach mogą pojawić się nowe linie, ale tak nie jest w przypadku Maven POM).


Jeśli używasz arkusza stylów, który podałem powyżej, dokładny skrypt będzie:

#!/bin/bash
IFS=$"n" read -r -d "" groupId artifactId version packaging 
< <(xsltproc stylesheet.xslt pom.xml) && printf "")

echo "pom.xml is for $groupId/$artifactId, version $version, with packaging $packaging"

0 dla odpowiedzi nr 2

Poniżej lepsza opcja przy użyciu xmllint. Przykładem jest skrypt powłoki, który zwraca wartość <version/> element:

#!/bin/bash
echo "setns ns=http://maven.apache.org/POM/4.0.0
cat /ns:project/ns:version/text()" | 
xmllint --shell pom.xml | egrep -v "^(/ >| -----)"

-2 dla odpowiedzi nr 3

Udało mi się to osiągnąć, pracując bezpośrednio nad źródłowym plikiem XML zamiast pracować z xsltproc. W moim skrypcie powłoki stworzyłem następującą zmienną:

GROUPID = "$ (grep -Po" (? <=) W + (? =) "Name_of_xml_file_here"