Php 将节点属性复制到父节点

Php 将节点属性复制到父节点,php,xml,xslt,Php,Xml,Xslt,我正在使用PHP5,我需要以以下形式转换XML: <section> <heading> <line absolutePage="4" page="2" num="35">A Heading</line> </heading> <subsection type="type1"> <heading label="3">

我正在使用PHP5,我需要以以下形式转换XML:

<section>
      <heading>
            <line absolutePage="4" page="2" num="35">A Heading</line>
      </heading>
      <subsection type="type1">
            <heading label="3">
                  <line absolutePage="4" page="2" num="36">A Subheading</line>
            </heading>
            <content/>
      </subsection>
</section>

标题
副标题
变成这样:

<section name="A Heading">
      <heading>
            <line absolutePage="4" page="2" num="35">A Heading</line>
      </heading>
      <subsection type="type1" label="3" name="A Subheading">
            <heading label="3">
                  <line absolutePage="4" page="2" num="36">A Subheading</line>
            </heading>
            <content/>
      </subsection>
</section>

标题
副标题
请注意,
标签
属性已从heading属性复制到父元素

另外,
标题/行
元素的文本已添加为父节点的属性。

此样式表:

<xsl:stylesheet version="1.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="subsection">
        <subsection label="{heading/@label}" name="{heading/line}">
            <xsl:apply-templates select="@*|node()"/>
        </subsection>
    </xsl:template>
    <xsl:template match="section">
        <section name="{heading/line}">
            <xsl:apply-templates select="@*|node()"/>
        </section>
    </xsl:template>
</xsl:stylesheet>

输出:

<section name="A Heading">
    <heading>
        <line absolutePage="4" page="2" num="35">A Heading</line>
    </heading>
    <subsection label="3" name="A Subheading" type="type1">
        <heading label="3">
            <line absolutePage="4" page="2" num="36">A Subheading</line>
        </heading>
        <content></content>
    </subsection>
</section>

标题
副标题
注意:只要可以使用文本结果元素和属性值模板,就使用它。这使得代码紧凑且快速。如果你想要更一般的答案,请澄清

编辑:缺少
部分/@name
。当然,如果空字符串
section/@label
不困扰您,您可以使用
section | subsection
模式匹配。

此样式表:

<xsl:stylesheet version="1.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="subsection">
        <subsection label="{heading/@label}" name="{heading/line}">
            <xsl:apply-templates select="@*|node()"/>
        </subsection>
    </xsl:template>
    <xsl:template match="section">
        <section name="{heading/line}">
            <xsl:apply-templates select="@*|node()"/>
        </section>
    </xsl:template>
</xsl:stylesheet>

输出:

<section name="A Heading">
    <heading>
        <line absolutePage="4" page="2" num="35">A Heading</line>
    </heading>
    <subsection label="3" name="A Subheading" type="type1">
        <heading label="3">
            <line absolutePage="4" page="2" num="36">A Subheading</line>
        </heading>
        <content></content>
    </subsection>
</section>

标题
副标题
注意:只要可以使用文本结果元素和属性值模板,就使用它。这使得代码紧凑且快速。如果你想要更一般的答案,请澄清


编辑:缺少
部分/@name
。当然,如果空字符串
section/@label
不困扰您,您可以使用
section | subsection
模式匹配。

@Alejandro,谢谢,效果很好,只需为'section'添加OR匹配项,这是缺少的。:)@本杰明·奥图扎:你很好。我也更新了答案。+1用于使用和覆盖标识转换以及使用AVTs@Alejandro,谢谢,效果很好,只需为“section”添加或匹配项,这是缺少的。:)@本杰明·奥图扎:你很好。我也更新了答案。+1用于使用和覆盖标识转换以及使用AVT