2017-01-25 11 views
0

に割り当てる:コマンドを実行私は、次のXML持つXMLパーサーを使用してXML要素から値を取得し、変数

<?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の私は、次のXSLTスタイルシートを持っている

また
 <?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> 

出力(のOutput.xmlファイルの内容)のOutput.xml "スタイルシート" "xml_fileは">です:

<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> 

達成したいことは次のとおりです。 シェルスクリプトで、 "BundleResourceDeploy"という要素 "groupId"の値を取得し、それを変数に割り当てたいとします。

これを達成する方法について教えてください。しかし、どのようなそのスクリプト内xmlstarletコマンドが実際にはあなたがすることによってあなたのために生成するXMLStarletを求めることができ、わずかに異なるXSLTテンプレート、と全く同等である

#!/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" 

答えて

0

個人的に、私はXMLStarletを使用したいです我々は、すべてここに私たちの出力の要素を作成するのではなく、改行で区切られたテキストストリームを生成していない

<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> 

注:-C引数を渡します。 (改行が私たちの値に現れるかもしれないなら、私たちのアプローチを調整する必要がありますが、これは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" 
+0

xmlshツールを見て、別の可能性があるが –

-2

私はソースXMLファイルで直接作業の代わりに、xsltprocのと協力して、それを達成するために管理しました。私のシェルスクリプトでは、私は次の変数を作成しました: " '??+ W(< =)\(=)' $(grepの-Po name_of_xml_file_here"

GROUPID =を

+1

はそれをしないでくださいこれは、1つのXMLファイルに働くかもしれないが、それは次回に失敗します。なぜなら、適切に構成されたXMLで合法的に発生するすべてのバリエーションを許可していないからです。将来の問題。 –

+0

より良いオプションを探して私はxmllintを使ってそれを解決しました。私は別の答えに投稿します – Alfonso

0

xmllintを使用して、より良いオプション以下の例。 <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 '^(/ >| -----)' 
+0

'--xpath'ではなく' --shell'を使っている理由はありますか? '--shell'はインタラクティブな使い方のために作られているので、プロンプトをstdoutに出力する(そしてプロンプト文字列を抽出された出力と混合する)ようなスクリプトには向いていないことをします。 –

+0

...インタラクティブな機能を一般的に定義されていないため、プログラマチックにインタラクティブに使用するツールを使用するのは危険です。現在のバージョンではプロンプトが '> 'であるからといって、たとえば、将来的には、このコードが引き続き機能するという保証はありません。対照的に、XSLTプロセッサの出力は*完全に*明確に定義されており、標準に準拠しなくなることなく任意の方法で変更することはできません。 –

+0

...だから、xmllintでこれを行うより安全な方法は、 'xmllint --xpath '/*[namespace-uri()="http://maven.apache.org/POM/4.0.0"となります。 local-name()= "project"]/* [namespace-uri()= "http://maven.apache.org/POM/4.0.0"およびlocal-name()= "version"]/text ) '' –

関連する問題