Xslt 复制XML并重命名其某些节点和嵌套节点
我需要将所有内容复制到新的XML中,除了一些需要重命名的元素 所有属于“node1”子节点的“child”节点需要重命名为“children”,属于“node2”子节点的“child”节点需要重命名为“kid” 完美的解决方案将使用Xslt 复制XML并重命名其某些节点和嵌套节点,xslt,xpath,Xslt,Xpath,我需要将所有内容复制到新的XML中,除了一些需要重命名的元素 所有属于“node1”子节点的“child”节点需要重命名为“children”,属于“node2”子节点的“child”节点需要重命名为“kid” 完美的解决方案将使用 match="/root/node1/descendant::child" 但正如我在迈克尔·凯对这个话题的回应中所发现的那样 形式/后代::m_uuid[1]的模式在这两种情况下都是不合法的 XSLT1.0或XSLT2.0,尽管在XSLT3.0中它是合法的 您对
match="/root/node1/descendant::child"
但正如我在迈克尔·凯对这个话题的回应中所发现的那样
形式/后代::m_uuid[1]的模式在这两种情况下都是不合法的
XSLT1.0或XSLT2.0,尽管在XSLT3.0中它是合法的
您对如何在XSLT2.0中做到这一点有什么建议,而不必执行下面的操作?因为我不知道到底会有多少窝
下面是我的xml示例
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<node2>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node2>
</root>
和XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/node1/child">
<xsl:element name="children">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="/root/node1/child/subnode/child">
<xsl:element name="children">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="/root/node2/child">
<xsl:element name="kid">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="/root/node2/child/subnode/child">
<xsl:element name="kid">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这对你有用吗
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="child">
<children>
<xsl:apply-templates select="@*|node()"/>
</children>
</xsl:template>
<xsl:template match="child[ancestor::node2]">
<kid>
<xsl:apply-templates select="@*|node()"/>
</kid>
</xsl:template>
</xsl:stylesheet>
您可以在模式中使用
//child
:
<xsl:template match="/root/node1//child">
<xsl:element name="children">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="/root/node2//child">
<xsl:element name="kid">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
我将使用文本结果元素而不是xsl:element:
<xsl:template match="/root/node1//child">
<children>
<xsl:apply-templates select="@*|node()"/>
</children>
</xsl:template>
<xsl:template match="/root/node2//child">
<kid>
<xsl:apply-templates select="@*|node()"/>
</kid>
</xsl:template>
此解决方案根本不使用任何谓词或轴,具有最短的匹配模式,因此比使用谓词的解决方案效率更高 当
有后代或祖先时,它也会产生预期的正确结果
——这是其他解决方案根本无法处理的
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" mode="#all">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node1" mode="#all">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="node1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node2" mode="#all">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="node2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="child" mode="node1">
<children>
<xsl:apply-templates select="node()|@*" mode="#current"/>
</children>
</xsl:template>
<xsl:template match="child" mode="node2">
<kid>
<xsl:apply-templates select="node()|@*" mode="#current"/>
</kid>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<root>
<node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<node2>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node2>
</root>
<root>
<node1>
<child>
<subnode>
<node2>
<child></child>
<node1>
<child/>
</node1>
</node2>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<node2>
<child>
<subnode>
<child></child>
</subnode>
</child>
<node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node2>
</root>
<root>
<node1>
<children>
<subnode>
<node2>
<kid/>
<node1>
<children/>
</node1>
</node2>
</subnode>
</children>
<children>
<subnode>
<children/>
</subnode>
</children>
</node1>
<node2>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
<node1>
<children>
<subnode>
<children/>
</subnode>
</children>
</node1>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
</node2>
</root>
生成所需的正确结果:
<root>
<node1>
<children>
<subnode>
<children/>
</subnode>
</children>
<children>
<subnode>
<children/>
</subnode>
</children>
</node1>
<node2>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
</node2>
</root>
在此XML文档上应用相同转换时,其中
和
是彼此的后代或祖先:
<root>
<node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<node2>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node2>
</root>
<root>
<node1>
<child>
<subnode>
<node2>
<child></child>
<node1>
<child/>
</node1>
</node2>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<node2>
<child>
<subnode>
<child></child>
</subnode>
</child>
<node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node2>
</root>
<root>
<node1>
<children>
<subnode>
<node2>
<kid/>
<node1>
<children/>
</node1>
</node2>
</subnode>
</children>
<children>
<subnode>
<children/>
</subnode>
</children>
</node1>
<node2>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
<node1>
<children>
<subnode>
<children/>
</subnode>
</children>
</node1>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
</node2>
</root>
再次生成正确且想要的结果(由其最近的祖先(即
或
)确定的
的替换名称):
<root>
<node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<node2>
<child>
<subnode>
<child></child>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node2>
</root>
<root>
<node1>
<child>
<subnode>
<node2>
<child></child>
<node1>
<child/>
</node1>
</node2>
</subnode>
</child>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<node2>
<child>
<subnode>
<child></child>
</subnode>
</child>
<node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node1>
<child>
<subnode>
<child></child>
</subnode>
</child>
</node2>
</root>
<root>
<node1>
<children>
<subnode>
<node2>
<kid/>
<node1>
<children/>
</node1>
</node2>
</subnode>
</children>
<children>
<subnode>
<children/>
</subnode>
</children>
</node1>
<node2>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
<node1>
<children>
<subnode>
<children/>
</subnode>
</children>
</node1>
<kid>
<subnode>
<kid/>
</subnode>
</kid>
</node2>
</root>
是的,它在我原来的10k行XML文档上运行良好。谢谢你的解决方案。你的解决方案对我也很好。谢谢回复。你能解释一下为什么要使用文字结果元素吗?当我必须向样式表标记添加排除结果前缀时,我只注意到使用文字时的区别,因为我在文件中使用名称空间。使用文字结果元素,您必须编写更少的代码,并且在我看来,样式表的功能更清晰(例如,将node1//child
映射到children
),我只在运行时需要计算元素的名称和/或命名空间时才使用xsl:element
。好的,我明白了。再次感谢。在我的原始文件中,我没有和是彼此的后代或祖先的情况,但感谢这个例子。我必须阅读一些关于“模式”的内容,我会将您的解决方案应用到我的原始文件中,看看它是如何工作的。@Elej,我很高兴这个答案不仅解决了您当前的问题,而且解决了未来的问题:)欢迎您进一步询问。