0

As part of a larger XML I have elements like <testdata>abc</testdata> and this String abc gets nicely put into a table cell <td>abc</td> using the following fragment in an XSLT file...

<td><xsl:value-of select="testdata"/></td>

Now what if the test data itself is HTML like this?

<testdata>
    <ol>
        <li>abc</li>
        <li>xyz</li>
    </ol>
</testdata>

Can I somehow enhance the above <xsl:value-of/> to take the whole content of the <testdata> element as it is? I keep losing the HTML formatting, resulting in <td>abcxyz</td>, but what I would expect is this:

<td>
    <ol>
        <li>abc</li>
        <li>xyz</li>
    </ol>
</td>

PS:

In some other related questions I found this xsl template as a solution. But I don't understand how I can apply such an identity copy to only the contents of my <testdata> element:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>  
</xsl:template>
dokaspar
  • 8,186
  • 14
  • 70
  • 98

2 Answers2

1

This template outputs <td> for each <testdata> element and then instructs the XSLT processor to do whatever is necessary to the contents.

<xsl:template match="testdata">
  <td>
    <xsl:apply-templates select="node() | @*" />
  </td>
</xsl:template>

If the identity template you mentioned is defined in your XSLT code and no other templates match any of the content of <testdata>, it will be copied as-is.

If your XSLT code is one huge templates with a lot of <xsl:for-each> (most beginner's XSLT code looks like that), then you will have to rewrite it a bit to use template matching efficiently (also see an explanation of template matching from an earlier question).

Community
  • 1
  • 1
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Thanks. I actually tried this before, but because `` is matched in the context of its parent node, this XSLT instruction also copies over the sibling elements of ``. Is there a way to narrow down the `select="node() | @*"` to something like `select="testdata/node() | @*"` – dokaspar May 22 '17 at 07:17
  • That's already what happens. Any `select` expression in XSLT works relative to the current context node. Inside an `` that's the respective `` element. What you actually need is an `` somewhere else. (Unless you opt for calling ``, like @michael.hor257k suggests. Then you don't need the identity template at all.) – Tomalak May 22 '17 at 07:59
1

Can I somehow enhance the above <xsl:value-of/> to take the whole content of the <testdata> element as it is?

Yes, you can change it to:

<xsl:copy-of select="testdata/node()"/>

You would not normally use the identity transform template in a document that outputs HTML, unless your input is HTML too.

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51