2016-01-20 100 views
1

我有下面的示例xml,我想从标记中提取值,例如value = 3。由于有重复的标签,我在unix中发现了这样做的挑战。从unix中重复的xml标记中提取值

<Request> 
<Destination> 
    <Parameters> 
     <Parameter> 
      <key>a</key> 
      <value>1</value> 
     </Parameter> 
     <Parameter> 
      <key>b</key> 
      <value>2</value> 
     </Parameter> 
     <Parameter> 
      <key>c</key> 
      <value>3</value> 
     </Parameter> 
    </Parameters> 
    <Proxy> 
     <Destination> 
      <Parameters> 
       <Parameter> 
        <key>a</key> 
        <value>1</value> 
       </Parameter> 
       <Parameter> 
        <key>b</key> 
        <value>2</value> 
       </Parameter> 
       <Parameter> 
        <key>c</key> 
        <value>3</value> 
       </Parameter> 
      </Parameters> 
     </Destination> 
    </Proxy> 
</Destination> 

回答

0

您可以尝试使用命令行XSLT处理器,就像“在xsltproc”或“xalan的”和使用的.xsl样式表解析您的.xml文件。这是一个引用你的示例XML数据的样式表。

我假设在您的文件末尾有一个对应于“请求”的结束标记。

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0"> 
    <xsl:output method = "text"/> 
    <xsl:template match = "Request"> 
    <xsl:for-each select = "Destination/Parameters/Parameter"> 
     <xsl:text>value=<xsl:value-of select = "@value"/> 
     </xsl:text> 
    </xsl:for-each> 
    <xsl:template match = "Proxy"> 
     <xsl:for-each select = "Destination/Parameters/Parameter"> 
      <xsl:text>value=<xsl:value-of select = "@value"/> 
      </xsl:text> 
     </xsl:for-each> 
    </xsl:template> 
    </xsl:template> 
</xsl:stylesheet> 
0

perl

#!/usr/bin/env perl 

use strict; 
use warnings; 
use XML::Twig; 

my $twig = XML::Twig -> new -> parsefile ('your_xml_file'); 

print $_ -> text,"\n" for $twig -> findnodes('//value'); 

从而降低到一个班轮:

perl -MXML::Twig -e 'print $_ -> text,"\n" for XML::Twig -> parse (do { local $/;<> } )-> findnodes('//value')' your_file.xml 

如果你想获得一个比较复杂一点有了它,你可以使用xpath表达式来查找特别的东西:

#!/usr/bin/env perl 

use strict; 
use warnings; 
use XML::Twig; 

my $twig = XML::Twig -> new -> parsefile ('your_file.xml'); 

foreach my $node ($twig -> findnodes('//value[string()="3"]/../')) { 
    print $node -> first_child_text('key'),"\n"; 
} 
1

通常,使用XQuery/XPath 3(例如在我的implementation)比XSLT。根据你所说的 “提取价值” 的意思,你可以做下列操作之一:

xidel req.xml --extract '//value' 

来获取所有值

1 
2 
3 
1 
2 
3 

或前缀:

xidel req.xml -e '//value/("value="||.)' 

得到

value=1 
value=2 
value=3 
value=1 
value=2 
value=3 

要得到所有的密钥与cer泰恩值:

xidel req.xml -e '//*[value="3"]/key' 

c 
c 

或者所有的值具有一定的键:

xidel req.xml -e '//*[key="b"]/value' 

2 
2