我有许多包含大量开销的XML文件。我希望只保留大约20个特定元素,并过滤掉其他任何内容。我知道我想要保留的所有元素的名字,我也知道它们是否是儿童元素,谁是他们的父母。我希望在转换后保留的这些元素仍然需要原始的层次结构放置。
E.g。我只想保持
<ns:currency>
在
<ns:stuff>
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code/>
<ns:currency_code2/>
<ns:currency_code3/>
<ns:currency_code4/>
</ns:things>
</ns:stuff>
让它看起来像这样;
<ns:stuff>
<ns:things>
<ns:currency>somecurrency</ns:currency>
</ns:things>
</ns:stuff>
构建XSLT以实现此目的的最佳方法是什么?
答案 0 :(得分:14)
这种一般转型:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="some:ns">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<ns:WhiteList>
<name>ns:currency</name>
<name>ns:currency_code3</name>
</ns:WhiteList>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[not(descendant-or-self::*[name()=document('')/*/ns:WhiteList/*])]"/>
</xsl:stylesheet>
应用于提供的XML文档(添加了命名空间定义以使其格式正确):
<ns:stuff xmlns:ns="some:ns">
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code/>
<ns:currency_code2/>
<ns:currency_code3/>
<ns:currency_code4/>
</ns:things>
</ns:stuff>
产生想要的结果(白名单元素及其结构关系被保留):
<ns:stuff xmlns:ns="some:ns">
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code3/>
</ns:things>
</ns:stuff>
<强>解释强>:
标识规则/模板“按原样”复制所有节点。
样式表包含一个顶级<ns:WhiteList>
元素,其<name>
个子元素指定所有列入白名单的元素的名称 - 要在文档中保留其结构关系的元素。
<ns:WhiteList>
元素最好保存在单独的文档中,以便不需要使用新名称编辑当前样式表。为方便起见,白名单在同一样式表中。
一个模板会覆盖身份模板。它不会处理(删除)任何未列入白名单且没有白名单后代的元素。
答案 1 :(得分:6)
在XSLT中,您通常不会删除要删除的元素,但是要复制要保留的元素:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://www.example.com/ns#"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/ns:stuff">
<xsl:copy>
<xsl:apply-templates select="ns:things"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns:things">
<xsl:copy>
<xsl:apply-templates select="ns:currency"/>
<xsl:apply-templates select="ns:currency_code3"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns:currency">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="ns:currency_code3">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
上述示例仅复制currency
和currency_code3
。输出如下:
<?xml version="1.0" encoding="UTF-8"?>
<ns:stuff xmlns:ns="http://www.example.com/ns#">
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code3/>
</ns:things>
</ns:stuff>
注意:我为前缀ns
添加了名称空间声明。
如果您要复制除少数元素之外的所有内容,您可能会看到此answer