我想改造
<?xml version="1.0" ?>
<mydoc>
<file>
<colors>
<blue />
<red />
<green />
</colors>
<secret>
<username />
<password />
</secret>
</file>
</mydoc>
到
<?xml version="1.0" ?>
<colors>
<blue />
<red />
</colors>
简单来说,我想递归复制colors元素,包括文本,忽略XML文档的其余部分并丢弃green元素。
有一些解决方案可以使用上面的示例,但如果XML略有不同,则会失败。例如,在颜色元素下添加嵌套元素,或在颜色<层次结构中添加其他元素/ strong>元素,或颜色元素范围内的文本(GOOD TEXT)和另一个超出其范围的文本(BAD TEXT)。
<?xml version="1.0" ?>
<mydoc>
<file>
<colors>
<nest>
<blue />
<red />
<green />
</nest>
GOOD TEXT
</colors>
<secret>
<username />
<password />
</secret>
BAD TEXT
</file>
<other>BAD TEXT TWO</other>
</mydoc>
我最感兴趣的是一个通用的解决方案,而不是根据此处提供的例子进行自定义。
答案 0 :(得分:2)
这种新变换足以复制颜色元素,无论其父级是什么。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/mydoc/file/colors">
<xsl:variable name="colors_parent"
select="local-name(.//green/parent::*)"/>
<xsl:copy>
<xsl:copy-of
select=".//*[local-name()=$colors_parent]/*[not(self::green)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
我还排除了所有可能的文本元素。如果你想保留“GOOD TEXT”文本节点,目前还不清楚。但是,现在应该很容易使变换适应新的要求。例如,如果您想在 colors 元素下保留任何文本节点,您可以更改使用此变换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/mydoc/file/colors">
<xsl:variable name="colors_parent"
select="local-name(.//green/parent::*)"/>
<xsl:copy>
<xsl:copy-of
select=".//*[local-name()=$colors_parent]/*[not(self::green)]
| .//text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
使用身份规则(它复制嵌套元素)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="mydoc">
<xsl:apply-templates select="file/colors"/>
</xsl:template>
<xsl:template match="green"/>
</xsl:stylesheet>
答案 1 :(得分:1)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<colors>
<xsl:apply-templates select="//colors/*[not(self::green)]"/>
</colors>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
输出:
<colors>
<blue />
<red />
</colors>