我有一个遵循这种整体模式的 xml 文档:
<A b="c" d="e" f="g" h="i">
<!-- plenty of children -->
</A>
我想复制 A
只有一些属性的节点:
<A b="c" f="g">
<!-- some of the children -->
</A>
这里的其他答案已接近解决我的挑战,但还不够:
- 这个答案给了我一个可行但会很长的解决方案:https://stackoverflow.com/a/672962/145978
- 所以我可以选择
<xsl:copy-of select="@*[(name()!='d') or (name()!='h']"/>
但我的实际属性列表很长。 - 我确实尝试寻找“是此列表的成员”类型的函数,但很快就迷路了。
- 所以我可以选择
- 这个答案似乎讨论了白名单,但我显然不够聪明,无法将其应用于属性选择:https://stackoverflow.com/a/5790798/145978
请帮忙
最佳答案
您链接的白名单解决方案使用包含应保留的元素列表的嵌入式文档。您可以为您的属性设置一个类似的属性:
<myns:whitelist>
<keep>b</keep>
<keep>f</keep>
</myns:whitelist>
可以使用 document('')
加载和解析它函数,您可以将它存储在一个变量中,以便于引用它:
<xsl:variable name="keep" select="document('')/*/myns:whitelist/keep"/>
现在 $keep
变量包含列表中所有属性的名称。星号代表 <xsl:stylesheet>
元素,因为参数传递给了 document()
是一个空字符串,这会导致它从当前文档加载。
然后您可以测试任意属性的名称是否与 $keep
中的任何一个匹配节点集:
@*[name()=$keep]
您使用身份转换复制的其他人。
这是您提供的示例的完整样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:myns="myns">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<myns:whitelist>
<keep>b</keep>
<keep>f</keep>
</myns:whitelist>
<xsl:variable name="keep" select="document('')/*/myns:whitelist/keep"/>
<xsl:template match="A">
<xsl:copy>
<xsl:apply-templates select="node()|@*[name()=$keep]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
关于xml - XSL : Copy Attributes That Match A Whitelist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23820874/