2

I have some xml which looks like this:

<row>
    <anode myattr1="value1" anotherAttr="notthis">
        blah
    </anode>
    <anothernode myattr1="value1" myattr2="value2" anotherAttr="notthis">
        blahBlah
    </anothernode>
</row>

I want to turn into something like this:

<tr>
    <td title="value1">
        blah
    </td>
    <td title="value1\nvalue2">
        blahBlah
    </td>
</tr>

So I'm trying to use the "fn:starts-with" to select these attribute values, but is not quite working. This is what I have so far:

<xsl:for-each select="row">
    <tr>                        
        <xsl:for-each select="./*">
            <xsl:variable name="title">
                <xsl:for-each select="./@[fn:starts-with(name(),'myattr')]">
                    <xsl:value-of select="."/>
                </xsl:for-each>
            </xsl:variable>
            <td title="$title"><xsl:value-of select="."/></td>
        </xsl:for-each>
    </tr>
</xsl:for-each>

But am getting an exception when I run this. Any help would be appreciated.

3
  • What is the exception? Is it because of the fn: prefix (which you don't need)? Commented May 23, 2011 at 23:50
  • or something like '@ must be followed by a NodeTest'? Commented May 23, 2011 at 23:57
  • The leading "./" in your path expressions is redundant but harmless. The leading "fn:" on function names is similarly redundant, but harmless if the prefix has been correctly declared. But the "@[predicate]" needs to be "@*[predicate]". Commented May 24, 2011 at 9:50

1 Answer 1

2

A short and simple transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="row/*">
     <td>
      <xsl:apply-templates select="@*[starts-with(name(),'myattr')][1]"/>
      <xsl:value-of select="."/>
     </td>
 </xsl:template>
 <xsl:template match="@*[starts-with(name(),'myattr')][1]">
  <xsl:attribute name="title">
   <xsl:value-of select="."/>
   <xsl:apply-templates select=
    "../@*[starts-with(name(),'myattr')][position()>1]"/>
  </xsl:attribute>
 </xsl:template>

 <xsl:template match="@*[starts-with(name(),'myattr')][position()>1]">
  <xsl:value-of select="concat('\n', .)"/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<row>
    <anode anotherAttr="notthis" myattr1="value1" >
             blah
  </anode>
    <anothernode anotherAttr="notthis" myattr1="value1" myattr2="value2" >
             blahBlah
 </anothernode>
</row>

the wanted, correct result is produced:

<tr>
   <td title="value1">
             blah
  </td>
   <td title="value1\nvalue2">
             blahBlah
 </td>
</tr>
Sign up to request clarification or add additional context in comments.

Comments

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.