xml - 将 XML 元素的名称替换为属性的值

标签 xml xslt

我的问题基于此:How to create XML nodes with attributes from Table

OP 要求有机会使用动态创建的元素名称创建 XML。

对于这个问题,XML 的生成并不重要(但可能会在原始帖子中进行跟踪)。

此 XML

<NodeA>
  <NodeB></NodeB>
  <NodeC AttributeX="">
    <Row NodeName="RowA" AttributeA="" AttributeB="abcd" AttributeC="efgh" />
    <Row NodeName="RowB" AttributeA="wxyz" />
    <Row NodeName="RowC" AttributeB="qwer" AttributeC="tyui" />
    <Row NodeName="RowD" AttributeA="stuv" AttributeB="erty" AttributeC="fghj" />
  </NodeC>
</NodeA>

应转换为:

<NodeA>
  <NodeB/>
  <NodeC AttributeX="">
        <RowA AttributeA="" AttributeB="abcd" AttributeC="efgh"/>
        <RowB AttributeA="wxyz"/>
        <RowC AttributeB="qwer" AttributeC="tyui"/>
        <RowD AttributeA="stuv" AttributeB="erty" AttributeC="fghj"/>
    </NodeC>
</NodeA>

唯一的区别是,“Row”元素的名称被“NodeName”属性值替换,并且“NodeName”属性本身消失了。

original post我建议使用 XSLT 方法 (Can be tested here)这可行,但在我看来太复杂了。有没有更好的方法来实现这个目标?

最佳答案

您应该首先使用身份模板,该模板本身将复制所有节点和属性

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

然后,您可以从要更改的节点添加模板;在此 Row 元素中具有 NodeName 属性。或者任何带有 NodeName 的元素都可以被转换。在这种情况下,模板匹配是这样的:

<xsl:template match="*[@NodeName]">

该模板的优先级高于身份模板,因此将首先匹配。需要注意的一件事是,在您链接到的问题中,有一个匹配“*”的模板和另一个匹配的“node()”。这两者具有相同的优先级,这被认为是错误。 XSLT 处理器可以标记错误,也可以选择最后一个模板。 (参见https://www.w3.org/TR/xslt#conflict)

无论如何,在模板内,您都可以创建一个名为 NodeName 属性的新元素

    <xsl:element name="{@NodeName}">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>

除此之外,您只需要另一个模板来确保 NodeName 属性本身不会获得输出。

试试这个 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[@NodeName]">
        <xsl:element name="{@NodeName}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@NodeName" />
</xsl:stylesheet>

关于xml - 将 XML 元素的名称替换为属性的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35523127/

相关文章:

c# - 意外的节点类型元素

xml-fo pdf 表 : 'colspan' when the number of columns is dynamic

xml - XSLT 替换存在于另一个元素值中的元素

javascript - 使用 JavaScript 将值从 HTML 传递到 XSLT

javascript - Adobe Air App 在中心启动

xml - 使用 Jenkins 显示自定义 HTML 或 XML 报告

xml - XSLT 格式日期

xml - 如何处理 XPath 2.0 表达式除以零的错误

java - Android:如何避免使用LayoutInflater将 View 组加倍

xml - 使用 XSLT 迭代具有命名空间的 XML 元素