omencat
omencat

Reputation: 1165

XSLT and dynamic attribute names

I have some XML that I am trying to transform to a more easily digestible XML file. The issue that I have is that element and attribute names have numbers at the end of them. I was able to get the first level of elements working with this:

  <xsl:template match="*[starts-with(name(), 'node')]" name="reports">

I am also able to create a template for section1 but I am not sure how to access its region* attribute within the template. This is what a sample of the original XML looks like:

<node01>
  <report>
    <section1 region1="World">
      ...
    </section1>
    <section2 region2="EU">
      ...
    </section2>
  <report>
<node01>

I am hoping to have output that looks something like:

<reports>
  <report>
    <region>
      <name>World</name>
      ...
    </region>
    <region>
      <name>EU</name>
      ...
    </region>
  <report>
<reports>

Upvotes: 0

Views: 1005

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117165

Not sure where you're stuck with this. Here's one way you could look at it:

XSLT 1.0

<xsl:stylesheet version="1.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="*"/>

<xsl:template match="/node01">
    <reports>
        <xsl:apply-templates/>
    </reports>
</xsl:template>

<xsl:template match="report">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*[starts-with(name(), 'section')]">
    <xsl:apply-templates select="@*"/>
</xsl:template>

<xsl:template match="@*[starts-with(name(), 'region')]">
    <region>
        <name><xsl:value-of select="."/></name>
    </region>
</xsl:template>

</xsl:stylesheet>

Here's another:

XSLT 1.0

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

<xsl:template match="/*">
    <reports>
        <xsl:for-each select="report">
            <xsl:copy>
                <xsl:for-each select="*/@*">
                    <region>
                        <name><xsl:value-of select="."/></name>
                    </region>
                </xsl:for-each>
            </xsl:copy>
        </xsl:for-each>
    </reports>
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions