【发布时间】:2018-04-19 10:18:00
【问题描述】:
我有一个结构如下的 XML 文件:
<?xml version = '1.0' encoding="ISO-8859-1"?>
<!DOCTYPE stuff PUBLIC "stuff" "stuff.dtd">
<stuff>
<level1>
<type>foo</type>
<name>name1_A</name>
<junk1>garbage</junk1>
<junk2>garbage</junk2>
<level2>
<name>name2_A</name>
<junk3>garbage</junk3>
<junk4>garbage</junk4>
<level3>
<name>name3_A</name>
<junk5>garbage</junk5>
<junk6>garbage</junk6>
</level3>
<level3>
<name>name3_B</name>
<junk5>garbage</junk5>
<junk6>garbage</junk6>
</level3>
</level2>
<level2>
<name>name2_B</name>
<junk>garbage</junk>
<level3>
<name>name3_A</name>
<junk>garbage</junk>
</level3>
<level3>
<name>name3_B</name>
<junk>garbage</junk>
</level3>
</level2>
</level1>
<level1>
<type>foo</type>
<name>name1_B</name>
<junk1>garbage</junk1>
<junk2>garbage</junk2>
<level2>
<name>name2_A</name>
<junk3>garbage</junk3>
<junk4>garbage</junk4>
<level3>
<name>name3_A</name>
<junk5>garbage</junk5>
<junk6>garbage</junk6>
</level3>
<level3>
<name>name3_B</name>
<junk5>garbage</junk5>
<junk6>garbage</junk6>
</level3>
</level2>
<level2>
<name>name2_B</name>
<junk>garbage</junk>
<level3>
<name>name3_A</name>
<junk>garbage</junk>
</level3>
<level3>
<name>name3_B</name>
<junk>garbage</junk>
</level3>
</level2>
</level1>
</stuff>
我想编写一个 XSLT 来过滤掉所有名为 junk* 的元素。也就是说,我知道我想要保留的元素名称并想要摆脱其他所有内容。上述起点的预期最终结果将如下所示,去掉所有垃圾元素:
<?xml version = '1.0' encoding="ISO-8859-1"?>
<!DOCTYPE stuff PUBLIC "stuff" "stuff.dtd">
<stuff>
<level1>
<type>foo</type>
<name>name1_A</name>
<level2>
<name>name2_A</name>
<level3>
<name>name3_A</name>
</level3>
<level3>
<name>name3_B</name>
</level3>
</level2>
<level2>
<name>name2_B</name>
<level3>
<name>name3_A</name>
</level3>
<level3>
<name>name3_B</name>
</level3>
</level2>
</level1>
<level1>
<type>foo</type>
<name>name1_B</name>
<level2>
<name>name2_A</name>
<level3>
<name>name3_A</name>
</level3>
<level3>
<name>name3_B</name>
</level3>
</level2>
<level2>
<name>name2_B</name>
<level3>
<name>name3_A</name>
</level3>
<level3>
<name>name3_B</name>
</level3>
</level2>
</level1>
</stuff>
请记住,我的示例中的各种垃圾元素可以命名为任何名称 - 我有我想要保留的元素名称列表(例如 level1/type、level1/name、level1/level2/name、level1/level2 /level3/name 等)并想放弃其他所有内容。
到目前为止我得到的最好的是这个 XSLT,但在这里我必须明确列出我想要删除的所有元素名称,而不是我想要保留的元素名称,所以它不太理想:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="junk1 | junk2 | junk3 | junk4 | junk5 | junk6"/>
</xsl:stylesheet>
【问题讨论】:
-
然后你必须明确地命名你想要保留的所有元素。由于垃圾元素可以出现在任何级别,因此编写一个模板来保留
<level1>但丢弃其中包含的任何垃圾元素将更加困难。你所拥有的已经是最佳方法,为什么你认为你可以改进它? -
如果您认为这已经是最佳选择...我不会争论!我花了一段时间寻找更好的方法无济于事。正如您所指出的,我的问题似乎是垃圾元素可以出现在任何级别。我找到了许多解决方案,可以处理他们都是特定级别的孩子,但不像我那样分散。