[英]Obtain value from XML element using XML parser and assign it to a variable
我有以下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>
我還有以下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>
執行命令:xsltproc“ stylesheet”“ xml_file”> output.xml
輸出(output.xml文件的內容)為:
<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>
我要實現的是:在shell腳本中,我想獲取元素“ groupId”的值(即“ BundleResourceDeploy”),並將其分配給變量。
您能幫我解決該問題的方法嗎?
就個人而言,我將使用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 '\0'
)
echo "pom.xml is for $groupId/$artifactId, version $version, with packaging $packaging"
但是,該腳本中xmlstarlet
命令的實際作用完全等同於稍有不同的XSLT模板,您可以要求XMLStarlet通過傳遞-C
參數為您生成該模板:
<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="' '"/>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="ns:artifactId"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="ns:version"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="ns:packaging"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</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()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
請注意,我們根本不會在輸出中創建元素,而是生成由換行符分隔的文本流。 (如果換行符可能出現在我們的值中,則需要調整方法,但在Maven POM中不是這種情況)。
如果您使用的是我上面提供的樣式表,則確切的腳本將是:
#!/bin/bash
IFS=$'\n' read -r -d '' groupId artifactId version packaging \
< <(xsltproc stylesheet.xslt pom.xml) && printf '\0')
echo "pom.xml is for $groupId/$artifactId, version $version, with packaging $packaging"
下面是使用xmllint
的更好的選擇。 該示例是一個shell腳本,該腳本返回<version/>
元素的值:
#!/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 '^(/ >| -----)'
我設法通過直接處理源XML文件而不是使用xsltproc來實現它。 在我的shell腳本中,我創建了以下變量:
GROUPID =“ $(grep -Po'(?<=)\\ w +(?=)'name_of_xml_file_here”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.