0

I'm very new to XSLT, and I'd like to know how to create a node based on the text of another node. For example, if have the XML:

<axis pos="6" values="3">
  <title>Device</title>
  <label code="7">Autologous Tissue Substitute</label>
  <label code="J">Synthetic Substitute</label>
  <label code="K">Nonautologous Tissue Substitute</label>
</axis>

I'd like to transform it into:

<stuff>
  <Device pos="6" code="7">Autologous Tissue Substitute</Device>
  <Device pos="6" code="J">Synthetic Substitute</Device>
  <Device pos="6" code="K">Nonautologous Tissue Substitute</Device>
</stuff>

I've tried the following XSLT, but it just spews errors at me:

<xsl:template match="axis">
  <stuff>
    <xsl:apply-templates select="label" />
  </stuff>
</xsl:template>
<xsl:template match="label">
  <xsl:element name="{../title}">
    <xsl:value-of select="text()" />
  </xsl:element>
  <xsl:attribute name="pos">
    <xsl:value-of select="../@pos" />
  </xsl:attribute>
  <xsl:attribute name="code">
    <xsl:value-of select="@code" />
  </xsl:attribute>
</xsl:template>
3
  • Your requested output is invalid: you need to have a root element. Commented Mar 30, 2014 at 23:07
  • fixed, for the pedantic Commented Mar 30, 2014 at 23:10
  • It's not about being pedantic (although it helps when you're dealing with code), it's about understanding what you're after. XSLT is very much context-dependent. Context issues are the reason why your attempt won't work: you have placed the attributes outside the <xsl:element> element. Place them inside (before the <xsL:value-of> element) and it will work. Commented Mar 30, 2014 at 23:31

3 Answers 3

1

I would do:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="axis">
  <stuff>
    <xsl:apply-templates select="label" />
  </stuff>
</xsl:template>

<xsl:template match="label">
  <xsl:element name="{../title}">
    <xsl:copy-of select="@code | ../@pos" />
    <xsl:value-of select="." />
  </xsl:element>
</xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

Comments

0

How about:

<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="/">
    <root>
        <xsl:for-each select="axis/label">
            <xsl:element name="{../title}">
                <xsl:attribute name="pos">
                    <xsl:value-of select="../@pos" />
                </xsl:attribute>
                <xsl:attribute name="code">
                    <xsl:value-of select="@code" />
                </xsl:attribute>
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

3 Comments

@JoeNahmias What am I looking at there?
click Run, then view source in the output pane
@JoeNahmias The input there is not the input here (apropos pedantic...)
0

This seems to work:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/root">
  <xsl:apply-templates select="axis" />
</xsl:template>
<xsl:template match="axis">
  <stuff>
    <xsl:apply-templates select="label" />
  </stuff>
</xsl:template>
<xsl:template match="label">
  <xsl:element name="{../title}">
    <xsl:attribute name="pos">
      <xsl:value-of select="../@pos" />
    </xsl:attribute>
    <xsl:attribute name="code">
      <xsl:value-of select="@code" />
    </xsl:attribute>
    <xsl:value-of select="." />
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

1 Comment

Your first template doesn't do anything (given the input here). You can delete it and it will keep working. BTW, most of us tend to put an empty line between templates to increase readability.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.