我需要制作XML处理例程,该例程会从提供给例程的XML文档中删除某些XML标记。 XML文档不是固定的,但已知它没有使用任何名称空间。
该例程将有两个XML标记名列表:
排除更具优势,即如果两个列表中的标记相同,则不应选择该标记。如果排除了父标记,则也应排除子标记。
我已经在网络上看到了很好的示例和答案,但在单个XSLT中找不到完全可行的解决方案来解决我的问题。
这个解决方案似乎非常明确和合理,但是有可能拥有" BlackList"也在同一个XSLT中?: XSLT - How to keep only wanted elements from XML
编辑:排除和包含列表彼此独立。即排除列表不包含所有不在包含列表中的标记,反之亦然。
EDIT2:需要简化的流程:XML - >删除排除标记 - >删除除包含标记以外的内容。
EDIT3:固定链接。
EDIT4:包含所有用例的维恩图(总是需要一个部分):
答案 0 :(得分:1)
---由于澄清而修改了答案---
以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://example.com/my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:whitelist>
<item>America</item>
<item>USA</item>
<item>California</item>
<item>LosAngeles</item>
<item>SanFranciso</item>
<item>Mexico</item>
<item>Tijuana</item>
</my:whitelist>
<my:blacklist>
<item>Mexico</item>
</my:blacklist>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(name()=document('')/*/my:whitelist/item) or name()=document('')/*/my:blacklist/item]"/>
</xsl:stylesheet>
应用于以下输入:
<强> XML 强>
<America>
<USA>
<NewYork>
<NewYork>no</NewYork>
<Albany>yes</Albany>
</NewYork>
<California>
<LosAngeles>no</LosAngeles>
<SanFranciso>no</SanFranciso>
</California>
</USA>
<Canada>
<Vancouver>no</Vancouver>
<Montreal>yes</Montreal>
</Canada>
<Mexico>
<Tijuana>no</Tijuana>
</Mexico>
</America>
将返回:
<?xml version="1.0" encoding="UTF-8"?>
<America>
<USA>
<California>
<LosAngeles>no</LosAngeles>
<SanFranciso>no</SanFranciso>
</California>
</USA>
</America>
当然,这只有在允许两个列表重叠时才有意义 - 即当黑名单覆盖白名单时。
如果您的处理器无法解析返回样式表本身的document()
函数,请尝试以下替代方法:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="whitelist">
<item>America</item>
<item>USA</item>
<item>California</item>
<item>LosAngeles</item>
<item>SanFranciso</item>
<item>Mexico</item>
<item>Tijuana</item>
</xsl:variable>
<xsl:variable name="blacklist">
<item>Mexico</item>
</xsl:variable>
<xsl:template match="*">
<xsl:if test="name()=exsl:node-set($whitelist)/item and not (name()=exsl:node-set($blacklist)/item)">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>