我有许多包含大量开销的XML文件.我希望只保留大约20个特定元素,并过滤掉其他任何内容.我知道我想要保留的所有元素的名字,我也知道它们是否是儿童元素,谁是他们的父母.我想在转换后保留的这些元素仍然需要原始的层次结构放置.
我想继续保持
<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>
Run Code Online (Sandbox Code Playgroud)
并使它看起来像这样;
<ns:stuff>
<ns:things>
<ns:currency>somecurrency</ns:currency>
</ns:things>
</ns:stuff>
Run Code Online (Sandbox Code Playgroud)
构建XSLT来实现这一目标的最佳方法是什么?
Dim*_*hev 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>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的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>
Run Code Online (Sandbox Code Playgroud)
产生想要的结果(白名单元素及其结构关系被保留):
<ns:stuff xmlns:ns="some:ns">
<ns:things>
<ns:currency>somecurrency</ns:currency>
<ns:currency_code3/>
</ns:things>
</ns:stuff>
Run Code Online (Sandbox Code Playgroud)
说明:
身份规则/模板"按原样"复制所有节点.
样式表包含一个顶级<ns:WhiteList>元素,其<name>子元素指定所有列入白名单的元素的名称 - 要在文档中保留其结构关系的元素.
该<ns:WhiteList>元素最好保存在单独的文档中,以便不需要使用新名称编辑当前样式表.为方便起见,白名单在同一样式表中.
一个模板覆盖了身份模板.它不处理(删除)任何未列入白名单且没有白名单后代的元素.
在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>
Run Code Online (Sandbox Code Playgroud)
上面的示例仅复制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>
Run Code Online (Sandbox Code Playgroud)
注意:我为您的前缀添加了名称空间声明ns.
如果要复制除少数元素之外的所有内容,您可能会看到此答案