How to parse XML DOM inside a CDATA element in XSLT?

Let's say I have an XML file, for example:

<library>
 <books>
  <![CDATA[<genre><name>Sci-fi</name><count>2</count></genre>]]>
  <book>
   <name>
    Some Book
   </name>
   <author>
    Some author
   </author>
  <book>
  <book>
   <name>
    Another Book
   </name>
   <author>
    Another author
   </author>
  <book>
 <books>
</library>

I want to read the name of the CDATA element in the xslt transformer and put its value somewhere in the tag area. How should I do it? AFAIK, we cannot use xpath for CDATA content. Is there any hack / workaround for this? I want to do this strictly in XSLT.

+5
source share
4 answers

Since CDATA blocks are (part of) text nodes, you can extract text between two “tags”, for example. eg:

<xsl:template match="text()">
  <xsl:value-of select="substring-before(substring-after(., '&lt;name>'), '&lt;/name>')"/>
</xsl:template>

This is just a quick idea. If there is more than one element name in CDATA, just recursively apply the above expression several times.

+2
source

XSLT , , saxon: parse(), , XML, .

+6

CDATA, XSL.

, CDATA :

<xsl:template match="//books/text()">
  <xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>

:

<genre><name>Sci-fi</name><count>2</count></genre>

XSL, XPATH, DOM. , CDATA XML. RegEx .

+3

, , . , "STR2XML", . - , . .

, :

<xsl:variable name="text">
    <![CDATA[
        <div style="color:red;">
            <p>hello world</p>
        </div>
    ]]>
</xsl:variable>
<p>
    <xsl:value-of select="$text"/>
</p>
<xsl:call-template name="str2xml">
    <xsl:with-param name="text" select="$text"/>
</xsl:call-template>

:

<div style="font-weight:bold;"> <p>hello world</p> </div> (non parsed plain text)

But of course, you can also use it to create a variable that can be accessed as node:

<xsl:variable name="text2">
    <![CDATA[
        <div>hello world</div>
        <p>goodbye world</p>
    ]]>
</xsl:variable>
<xsl:variable name="var1">
    <xsl:call-template name="str2xml">
        <xsl:with-param name="text" select="$text2"/>
    </xsl:call-template>
</xsl:variable>
<xsl:for-each select="xalan:nodeset($var1)/*">
    <p>
        <xsl:value-of select="concat(name(.),': ',.)"/>
    </p>
</xsl:for-each>

Conclusion:

div: hello world

p: good peace

+1
source

All Articles