我有一个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>
答案 0 :(得分:0)
如果它们在名称中共享一些共同的特征,则可以将它们重新组合在不同的类别中,而不是枚举您想要忽略的所有节点名称:
//*[starts-with(name(), 'junk')]
//*[ends-with(name(), 'junk')]
//*[contains(.,'junk')]
如果您不确切知道要删除的标记的名称,则可以更改XSLT的逻辑,并仅应用于要保留的节点的名称和复制操作。
如果您只知道要忽略的标记的名称,请使用以下逻辑:
如果“node”表示元素,则使用:
<xsl:template match="*[not(self::ServiceNode)]">
如果“node”表示任何节点(类型为元素,文本,注释,处理指令):使用
<xsl:template match="node()[not(self::ServiceNode)]">
如果您只想匹配Document的子项,请使用:
<xsl:template match="Document/node()[not(self::ServiceNode)]">
如果您只想匹配top元素的子元素,请使用:
<xsl:template match="/*/node()[not(self::ServiceNode)]">
How to write a xpath to match all elements except a particular element