tags:

views:

19

answers:

1

Im working with PHP5, and I need to transform XML in the following form:

<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>

Into something like this:

<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>

Note that the label attribute has been been copied from the heading attribute to the parent element.

Also the text of the heading/line element has been added as an attribute of the heading parent node.

Thanks,

+3  A: 

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <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>

Output:

<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>

Note: Whenever is posible to use literal result elements and attributes value template, use it. That make code compact and fast. If you want more general answer, clarify that please.

Edit: Missed section/@name. Of course, if empty string section/@label doesn't bother you you could use section|subsection pattern matching.

Alejandro
@Alejandro, thanks works great, just add the OR match for 'section', that is missing. :)
Benjamin Ortuzar
@Benjamin Ortuzar: You are wellcome. I've updated the answer, too.
Alejandro
+1 for using and overriding the Identity transform and for using AVTs
Dimitre Novatchev