仅保留列入白名单的元素和/或属性 [英] keep only white-listed elements and/or attributes
问题描述
我有一个包含大量节点的 XML 文件,每个节点都有大量的属性.为简单起见,让我们假设 XML 如下所示:
I have an XML file with a plethora of nodes, each having a vast amount of attributes. For simplicity, let us assume the XML looking like this:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<header />
<group>
<node1 attr1="x" attr2="y" attr3="z" />
<node2 attr4="x" attr5="y" attr6="z" />
<node3 attr7="x" attr8="y" attr9="z" />
<node1 attr1="x" attr2="y" attr3="z" />
</group>
</root>
我想通过消除属性和节点来减少 /root/group/
的内容,从而将这个 XML 缩减为更小的版本.
I would like to reduce this XML into a smaller version by reducing the content of /root/group/
by eliminating both attributes as well as nodes.
- 应该删除所有名为
node3
的节点 - 名称为
node1
的节点应该只有属性attr1
- 名称为
node2
的节点应该只有属性attr5
和attr6
- all nodes with name
node3
should be removed - The nodes with name
node1
should only have attributeattr1
- The nodes with name
node2
should only have attributesattr5
andattr6
我可以通过使用简单的 if-match-do-nothing 来为此编写一个简单的 XSLT,例如.
I could write a simple XSLT for this by making use of simple if-match-do-nothing, eg.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/root/group/node3" />
<xsl:template match="/root/group/node1/@attr2" />
<xsl:template match="/root/group/node1/@attr3" />
<xsl:template match="/root/group/node2/@attr4" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
然而,这不符合我的需求.以上说明了我不想要的内容,但我想通过使用 来说明我想要的内容白名单 我发现的两个问题部分回答了这个问题.一个问题介绍了节点的白名单,另一个问题 介绍了属性的白名单.我怎样才能在一个白名单中优雅地做到这一点,或者有更好的方法吗?这可以在表单的白名单中完成吗:
This, however, does not fit my needs. The above states what I do not want, but I would like to state what I do want by making use of a whitelist Two questions I found answered this question partially. One question introduced the whitelist for the nodes, the other question introduced the whitelist for the attributes. How can I do this elegantly in a single whitelist or is there a better method? Can this be done in a whitelist of the form:
<whitelist>
<node1 attr1="" />
<node2 attr5="" attr6="" />
</whitelist>
备注:我只能使用 XSLT-1.0
Remark: I can only use XSLT-1.0
预期输出:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<header />
<group>
<node1 attr1="x" />
<node2 attr5="y" attr6="z" />
<node1 attr1="x" />
</group>
</root>
<小时>
相关问题:
推荐答案
这对你有用吗?有一个模板匹配group
元素的子元素,然后查看白名单文档看是否复制该节点,如果复制,哪些属性也应该复制
Would this do it for you? Have a single template that match children of the group
elements, and then check the white list document to see whether to copy that node, and if so, what attributes should be copied too
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="ns" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<ns:WhiteList>
<node>
<name>node1</name>
<attr>attr1</attr>
</node>
<node>
<name>node2</name>
<attr>attr5</attr>
<attr>attr6</attr>
</node>
</ns:WhiteList>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="group/*">
<xsl:variable name="node" select="document('')//ns:WhiteList/node[name = name(current())]" />
<xsl:if test="$node">
<xsl:copy>
<xsl:apply-templates select="@*[name() = $node/attr]|node()" />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这篇关于仅保留列入白名单的元素和/或属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!