Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

"Unwrap" CDATA with XSLT

Mentor ,
Jun 12, 2008 Jun 12, 2008
Hi,

I know this isn't necessarily a FrameMaker question, but it is a place where I know people. So forgive me for asking it here.

I have some CDATA sections in an XML file that contain markup that I want to be parsed eventually, and I want to be able to extract it with the markup intact. Can I do this with XSLT, or does the nature of CDATA negate the use of retrieving the markup with an XML-parser-dependent technology?

Here's a sample element (element tags replaced with curly braces)

{documentation}{![CDATA[{p}Some text{/p}]]}{/documentation}

Is there any way I can get that p element out of there with XSLT, without excaping any of the characters, so it is parsable markup in the output?

[{p}Some text{/p}

Thanks,
Russ
TOPICS
Structured
11.1K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Jun 12, 2008 Jun 12, 2008
Hi Russ,

I didn't totally catch the problem (friday..?), but these hints might help you:

Text nodes and element nodes differ a bit in XSLT:

- CDATA nodes do not have any name
- "*" matches only elements
- "text()" matches only CDATA nodes
- "node()" matches both element and CDATA nodes

also you could use modes to selectively process text nodes (assuming p contains only cdata)

-- elements--
xsl:template match="*"
xsl:element="{name()}"
xsl:apply-templates/
/xsl:element
/xsl:template

xsl:template match="p"
xsl:element="{name()}"
xsl:apply-templates mode="text"/
/xsl:element
/xsl:template

xsl:template match="text()"/ -- drop text nodes--

xsl:template match="text()" mode="text"
xsl:value-of select="."/
/xsl:template

Martti
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 13, 2008 Jun 13, 2008
Hi Russ, Martti,

In the XSLT model there is no such thing as a CDATA node, so the statement that "'text()' matches only CDATA nodes" cannot be true. The 'text()' construct only matches text nodes. It's this lack of a CDATA node type that prevents XSLT processing CDATA sections in a specific way.

Regards
Ian
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Mentor ,
Jun 13, 2008 Jun 13, 2008
Thanks guys. The problem is that when I copy-of or value-of some text out of a ![CDATA[]] node, all angle brackets are replaced by the standard entities in the output. Therefore, when I run the output (which is another XML file) through an XML parser, any element tags that were originally in the !CDATA are not parsed. I need the element tags in the !CDATA node to become real tags in the output.

I hope I'm making sense. I'm experimenting with this in XML Spy, if that is relevant. Ultimately, though, it is for a stylesheet for import of XML into Frame.

Russ
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Jun 13, 2008 Jun 13, 2008
Russ,

Two XSLT 1.0 attributes that might allow you to accomplish what you want are:


  1. <xsl:output cdata-section-elements="documentation">

    This XSLT element tells the XSLT processor to always output text nodes within documentation elements as CDATA sections. Hence, with this <xsl:output> element and the template:

    <xsl:template match="documentation">

      <xsl:copy>

        <xsl:apply-templates/>
      </xsl:copy>
    </xsl:template

    your original example would be output as itself:

    <documentation><![CDATA[<p>Some text</p>]]></documentation>

    It gets more complicated if you want to illustrate CDATA sections in your documentation element.
     

  2. <xsl:value-of disable-output-escaping="yes">

    tells the processor to output those special characters that are interpreted by an XML parser as themselves instead of as one of the XML representations of those characters. Thus, you can try:

    <xsl:template match="documentation">
      <xsl:copy>
        <xsl:value-of disable-output-escaping="yes" select="."/>
      </xsl:copy>
    </xsl:template

--Lynne
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Mentor ,
Jun 13, 2008 Jun 13, 2008
LATEST
Lynne,

Magnificent. The second solution is exactly what I wanted. I thought there was an attribute like that, but the XML Spy auto-complete assistant didn't offer it, so I got lazy and didn't look it up. Thanks a million.

Russ
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines