我需要维护XML文档的结构,但只需删除所有不具有指定ID的detail
元素(在以下示例中,我只想保留id="1"
。代码示例只有三个级别(A,B,C),但是假设代码模式可以无限期地继续。我是否可以在XML上使用xpath来修剪掉与id不匹配的所有detail
元素保持树?
输入
<A>
<B>
<C>
<details id="1">...</details>
<details id="2">...</details>
</C>
<C>
<details id="1">...</details>
<details id="2">...</details>
</C>
<details id="1">...</details>
<details id="2">...</details>
</B>
<B>
<C>
<details id="1">...</details>
<details id="2">...</details>
</C>
<C>
<details id="1">...</details>
<details id="2">...</details>
</C>
<details id="1">...</details>
<details id="2">...</details>
</B>
<details id="1">...</details>
<details id="2">...</details>
</A>
所需输出
<A>
<B>
<C>
<details id="1">...</details>
</C>
<C>
<details id="1">...</details>
</C>
<details id="1">...</details>
</B>
<B>
<C>
<details id="1">...</details>
</C>
<C>
<details id="1">...</details>
</C>
<details id="1">...</details>
</B>
<details id="1">...</details>
</A>
答案 0 :(得分:1)
怎么样:
XSLT 1.0
namespace ClipboardAssistant.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Collections.ObjectModel.ObservableCollection<ClipboardAssistant.Models.Copyable> Copyables {
get {
return ((global::System.Collections.ObjectModel.ObservableCollection<ClipboardAssistant.Models.Copyable>)(this["Copyables"]));
}
set {
this["Copyables"] = value;
}
}
}
}
请注意,这假设已移除的<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="details[not(@id='1')]"/>
</xsl:stylesheet>
元素没有您要保留的任何子项。
答案 1 :(得分:0)
使用正确的XML解析器
非常简单此程序使用XML::Twig
。它只是解析XML文件,使用XPath表达式查找id不是1的所有details
元素并删除它们,然后打印结果
输入XML文件需要作为命令行上的参数
use strict;
use warnings 'all';
use XML::Twig;
my ($xml_file) = @ARGV;
my $twig = XML::Twig->new;
$twig->parsefile($xml_file);
$_->delete for $twig->findnodes('//details[@id != 1]');
$twig->set_pretty_print('indented');
$twig->print;
<A>
<B>
<C>
<details id="1">...</details>
</C>
<C>
<details id="1">...</details>
</C>
<details id="1">...</details>
</B>
<B>
<C>
<details id="1">...</details>
</C>
<C>
<details id="1">...</details>
</C>
<details id="1">...</details>
</B>
<details id="1">...</details>
</A>