假设我在文件中有以下行(不要将其视为XML文件):
<AVP code="123" name="abcd">
<type>
<high/>
</type>
</AVP>
<AVP code="234" name="ukbkj">
<type>
<enum/>
<type>
<enum name="erdf"/>
</AVP>
我想从(例如)AVP代码123中删除匹配/ AVP,以便删除AVP 123的所有数据。我怎样才能做到这一点? 这是输出应该是什么样子。我想保存到文件,而不是打印到标准输出。
<AVP code="234" name="ukbkj">
<type>
<enum/>
<type>
<enum name="erdf"/>
</AVP>
答案 0 :(得分:1)
通过perl。
$ perl -0777pe 's/<AVP code="123".*?<\/AVP> *\n//sg' file
<AVP code="234" name="ukbkj">
<type>
<enum\>
<type>
<enum\>
<AVP code>
通过python。
import re
with open('file') as f:
m = f.read()
splt = re.findall(r'(?s)<AVP\s+code="\d+".*?</AVP>', m)
for i in splt:
if '<AVP code="123"' not in i:
print(i, end="")
答案 1 :(得分:0)
如果您的输入是XML,它看起来像这样:
<?xml version="1.0"?>
<root>
<AVP code="123" name="abcd">
<type>
<high/>
</type>
</AVP>
<AVP code="234" name="ukbkj">
<type>
<enum/>
</type>
<type>
<enum/>
</type>
</AVP>
</root>
您可以使用此XSLT删除所有AVP
元素。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="no"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="AVP[@code='123']" />
</xsl:stylesheet>
使用Python应用它:
import lxml.etree as ET
dom = ET.parse("avp.xml")
xslt = ET.parse("avp.xslt")
transform = ET.XSLT(xslt)
newdom = transform(dom)
with open("avp-out.xml", "wb") as o:
o.write(ET.tostring(newdom, pretty_print=True))
avp-out.xml
中的输出:
<root>
<AVP code="234" name="ukbkj">
<type>
<enum/>
</type>
<type>
<enum/>
</type>
</AVP>
</root>
答案 2 :(得分:0)
更合适的方法是使用XML解析库,XML::LibXML
是一个很好的解析库。请注意,您当前的示例是不有效的XML:
use strict;
use warnings;
use XML::LibXML;
my $xml_filename = $ARGV[0];
die "Missing name of xml file to parse"
unless $xml_filename;
open(my $xml_file, '<', $xml_filename)
or die "Error opening XML file: $!";
my $dom = XML::LibXML->load_xml(IO => $xml_file);
foreach my $node ( $dom->findnodes('/root/AVP') ) {
$node->unbindNode()
if $node->getAttribute('code') == 123;
}
open(my $out_fh, '>', "${xml_filename}.out")
or die "Unable to open outfile: $!";
binmode $out_fh;
# write XML tree to file
$dom->toFH($out_fh);
close($out_fh);
答案 3 :(得分:0)
使用XML::Twig
- 复制Lutz Horn提到的固定XML:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
sub delete_if_code_123 {
my ( $twig, $AVP ) = @_;
if ( $AVP->att('code') eq "123" ) {
$AVP->delete;
}
}
my $twig = XML::Twig->new(
pretty_print => 'indented',
twig_handlers => { 'AVP' => \&delete_if_code_123 },
);
$twig ->parse( \*DATA );
$twig -> print;
__DATA__
<?xml version="1.0"?>
<root>
<AVP code="123" name="abcd">
<type>
<high/>
</type>
</AVP>
<AVP code="234" name="ukbkj">
<type>
<enum/>
</type>
<type>
<enum/>
</type>
</AVP>
</root>