使用XPATH从不同的子元素中提取值

时间:2017-08-22 20:36:18

标签: xml bash ubuntu xpath

目前我正面临一个xml文件,该文件基本上如下所示,但有数千个元素:

<Data>
    <Elements>
      <Element>
        <Subentry1>Value1</Subentry1>
        <Subentry2>MoreData</Subentry2>
      </Element>
      <Element>
        <Subentry1>Value2</Subentry1>
        <Subentry2>MuchMoreData</Subentry2>
      </Element>
     </Elements> </Data>

我正在使用Ubuntu,并希望打印值Subentry1和Subentry2的每个组合。对于上述示例,希望的输出是:

  

Value1_MoreData

     

Value2_MuchMoreData

在阅读了有关XPATH字符串连接函数的内容并尝试了不支持XPATH 2.0的无穷无尽的ubuntu工具之后,我得到了以下工作解决方案(bash脚本):

totalNumber=$(xmllint --xpath 'count(//Element)' example.xml)
i=1
while [ $i -le $totalNumber ]
do
   xmllint --xpath "concat((//Element)[$i]/Subentry1/text(),'_',(//Element)[$i]/Subentry2/text())" example.xml
   echo -e "" 
   let i=$i+1
done

但是,如果你想处理例如10000个元素。如果有专家能给我提示,我会很高兴。

2 个答案:

答案 0 :(得分:2)

如果您能够使用xmlstarlet,则可以执行以下操作:

==> xml sel -t -m "/Data/Elements/Element" -v "concat(Subentry1,'_',Subentry2)" -n test.xml
Value1_MoreData
Value2_MuchMoreData

答案 1 :(得分:2)

@Daniel Haley的回复似乎比我发布的建议简洁得多。我需要看一下xmlstarlet,看起来比XSLT要紧。尽管如此,这是一个使用XSLT的解决方案:

$ xsltproc template.xsl input.xml 

    Value1_MoreData
    Value2_MuchMoreData

$ cat template.xsl 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" />
<xsl:template match="//Element">
  <xsl:value-of select="Subentry1"/>_<xsl:value-of select="Subentry2"/>
</xsl:template>
</xsl:stylesheet>


$ cat input.xml 
<?xml version="1.0"?>
<Data>
  <Elements>
    <Element>
      <Subentry1>Value1</Subentry1>
      <Subentry2>MoreData</Subentry2>
    </Element>
    <Element>
      <Subentry1>Value2</Subentry1>
      <Subentry2>MuchMoreData</Subentry2>
    </Element>
  </Elements>
</Data>