从unix中重复的xml标记中提取值

时间:2016-01-20 11:15:16

标签: xml unix

我有以下示例xml,我想从标签中提取值,例如value = 3。由于有重复的标签,我发现在unix中执行此操作的挑战。

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

3 个答案:

答案 0 :(得分: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

获取具有特定值的所有键:

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

c
c

或具有特定键的所有值:

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

2
2

答案 1 :(得分:0)

您可以尝试使用命令行XSLT处理器,例如&#39; xsltproc&#39;或者&#39; xalan&#39;并使用.xsl样式表解析.xml文件。这是一个样式表,它引用了您的示例x​​ml数据。

我假设有一个结束标记对应于&#39;请求&#39;在你的文件的末尾。

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

答案 2 :(得分: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";
}