我有以下示例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>
答案 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文件。这是一个样式表,它引用了您的示例xml数据。
我假设有一个结束标记对应于&#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";
}