How to get CDATA from xml node using xsl?

I am trying to get the CDATA content of an XML node using XSL. node currently looks like this:

 <node id="1" text="Book Information" ><![CDATA[This is sample text]]></node> 

I need a portion of This is sample text . Does anyone know about this?

Thanks in advance.

+6
xml cdata xslt
source share
5 answers

Some other easy steps to achieve this;
Used by the W3cschools editor to try it out. Sample XML file:

 <?xml version="1.0" encoding="ISO-8859-1"?> <!-- Edited by XMLSpy® --> <catalog> <cd> <disk id="title"><![CDATA[Sample xml]]></disk > <disk id="artist"><![CDATA[Vijay]]></disk > </cd> </catalog> 


Example XSL file:

 <?xml version="1.0" encoding="ISO-8859-1"?> <!-- Edited by XMLSpy® --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>Title</th> <th>Artist</th> </tr> <xsl:for-each select="catalog/cd"> <tr> <td><xsl:value-of select="/catalog/cd/disk[@id='title']"/></td> <td><xsl:value-of select="/catalog/cd/disk[@id='artist']"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> 


Final result;
alt text

+1
source share

Well, if I use this stylesheet:

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="node/text()"> <xsl:copy/> </xsl:template> </xsl:stylesheet> 

in this xml file:

 <?xml version="1.0" encoding="utf-8"?> <node id=1 text="Book Information" ><![CDATA[This is sample text]]></node> 

I get a parsing error because id=1 is invalid XML.

Putting quotes around the attribute value ( id="1" ) and repeating the stylesheet, I get the output:

This is a sample text.

So, let's begin. Basically, just treat CDATA as node text and you're on your way.

You said:

I found something like:
<xsl:output cdata-section-elements="text"/>
and then pick up CDATA:
<xsl:value-of select="node" />

This approach works very well if you use value-of . There will be an example according to your comments, use value-of instead. Note, however, that cdata-section-elements only works on the output side, indicating which output XML elements you want to print as CDATA sections instead of the usual old character data. This has nothing to do with data mining.

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output cdata-section-elements="foo"/> <xsl:template match="/"> <foo> <xsl:value-of select="node"/> </foo> </xsl:template> </xsl:stylesheet> 

displays

 <?xml version="1.0"?> <foo><![CDATA[This is sample text]]></foo> 
+10
source share

For CDATA output partitions:

You should use xsl:output/@cdata-section-elements . From http://www.w3.org/TR/xslt#output

The cdata-section-elements attribute contains a list separated by spaces from QNames. Each QName is expanded by an expanded name using the declaration namespace, acting on xsl: the output element in which the QName takes place; if there is a default namespace, it is used for QNames that do not have a prefix. Extension performed before merging Several xsl: output elements are output into a single effective xsl: output element. If the extended parent name of the text node is a member of the list, then the text node should be displayed as a CDATA section.

Except DOE , of course.

You cannot select CDATA partitions using XPath. According to http://www.w3.org/TR/xpath/#data-model

There are seven types of node:

  • root nodes

  • element nodes

  • text nodes

  • attribute nodes

  • namespace nodes

  • processing instruction nodes

  • comment nodes

And from http://www.w3.org/TR/xpath/#section-Text-Nodes

Each character in the CDATA section is treated as character data. Thus, <![CDATA[<]]> in the source document will be processed in the same way as <. Both of these will result in the node text in the tree. Thus, the CDATA partition is treated as if <![CDATA[ and ]]> were deleted, and each occurrence of < and & was replaced by &lt; and &amp; respectively.

0
source share

The only solution I found on the internet that works is this

 {XSLT} <title> <xsl:text disable-output-escaping="yes"><![CDATA[ <![CDATA[ ]]></xsl:text> <xsl:value-of select="label" disable-output-escaping="yes"/> <xsl:text disable-output-escaping="yes"><![CDATA[]]]]><![CDATA[>]]></xsl:text> </title> 

However, these are not the cleanest solutions, especially if you need to implement this in different parts of XSLT. In addition, if your input XML already has CDATA (i.e. you are trying to save CDATA), using the disable-output-escaping function will not work, since by that time CDATA has already been parsed by the XSLT engine, and all that content will be left behind , which may eventually break xml.

Here is my solution -

Depending on how you use XSLT, you can use external / injected functions. By doing this, you can easily minimize the amount of code you write and end up with a much more beautiful template:

 {C#} public string CDATAWrap(string data) { return "<![CDATA[" + data + "]]>"; } {XSLT} <title> <xsl:value-of select="CDataType:CDATAWrap(label)" disable-output-escaping="yes" /> </title> 
0
source share

I tried with various combinations and got a solution for this;

  <xsl:value-of select="/node/."/> 
-one
source share

All Articles