从xml中删除所有节点,使用XSLT排除特定节点
问题描述:
我有一堆xml文件,其中有不同数量的节点,我想使用XSLT更改文件以仅包含特定节点。 例子:从xml中删除所有节点,使用XSLT排除特定节点
<?xml version="1.0" encoding="UTF-8"?>
<SomeName>
<identifier>
<UID> 1234 </UID>
</identifier>
<MainNode1>
<SubNode1>
<Subnode1a>DATA1a0</Subnode1a>
</SubNode1>
<SubNode1>
<Subnode1a>DATA1a1</Subnode1a>
</SubNode1>
<SubNode1>
<Subnode1a>DATA1a2</Subnode1a>
</SubNode1>
</MainNode1>
<MainNode2>
<SubNode2>
<Subnode2a>DATA2a0</Subnode2a>
</SubNode2>
</MainNode2>
<MainNodeIDONTCARE>
<SubnodeWhatever>
</SubnodeWhatever>
</MainNodeIDONTCARE>
<MainNodeuseless>
<SubnodeWhatever>
</SubnodeWhatever>
</MainNodeuseless>
<MainNodewhatever>
<SubnodeWhatever>
</SubnodeWhatever>
</MainNodewhatever>
</SomeName>
现在我的最后的XML文件看起来应该像:
<?xml version="1.0" encoding="UTF-8"?>
<SomeName>
<identifier>
<UID> 1234 </UID>
</identifier>
<MainNode1>
<SubNode1>
<Subnode1a>DATA1a0</Subnode1a>
</SubNode1>
<SubNode1>
<Subnode1a>DATA1a1</Subnode1a>
</SubNode1>
<SubNode1>
<Subnode1a>DATA1a2</Subnode1a>
</SubNode1>
</MainNode1>
<MainNode2>
<SubNode2>
<Subnode2a>DATA2a0</Subnode2a>
</SubNode2>
</MainNode2>
</SomeName>
我一直在试图把它与XSLT做,但我似乎无法完成它。
感谢您的任何帮助。
答
这应该工作:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="SomeName">
<xsl:copy>
<xsl:for-each select="identifier|MainNode1|MainNode2">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答
这
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="SomeName">
<xsl:copy>
<xsl:for-each select="identifier|MainNode1|MainNode2">
<xsl:apply-templates select="." />
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
+0
根据OP的要求,不包括标识符,MainNode1,MainNode2。 – AxelEckenberger 2010-05-26 16:38:13
+0
@Obalix:感谢您的评论,我以我自己的方式纠正了错误。 您的解决方案也很好。 – Gart 2010-05-26 16:44:35
答
可能最短的解决方案是以下:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="MainNodeIDONTCARE | MainNodeuseless | MainNodewhatever"/>
</xsl:stylesheet>
当这种变换的应用提供了XML文档,wante d产生输出:
<SomeName>
<identifier>
<UID> 1234 </UID>
</identifier>
<MainNode1>
<SubNode1>
<Subnode1a>DATA1a0</Subnode1a>
</SubNode1>
<SubNode1>
<Subnode1a>DATA1a1</Subnode1a>
</SubNode1>
<SubNode1>
<Subnode1a>DATA1a2</Subnode1a>
</SubNode1>
</MainNode1>
<MainNode2>
<SubNode2>
<Subnode2a>DATA2a0</Subnode2a>
</SubNode2>
</MainNode2>
</SomeName>
请注意,使用了最根本的XSLT设计模式:使用并重写身份规则。
好问题(+1)。请参阅我的答案,了解最简单的解决方案,它也完全符合XSLT的精神,并且不使用任何''指令。 :) –
2010-05-26 16:55:17