I have several unordered lists in an XML file that I need to convert to HTML with an XSL file. These lists inside my XML look like:
<Food>
<FoodItem ID="1">
<Content><![CDATA[<ul><li>Apples</li><li>Pears</li><li>Oranges</li><ul>]]></Content>
</FoodItem>
</Food>
I would like to grab the unordered lists from the XML file and output them in my XSL file like so that I can stlye them with CSS. The result should be like this:
<div class="food">
<ul class="fooditems">
<li class="fooditem">Apples</li>
<li class="fooditem">Pears</li>
<li class="fooditem">Oranges</li>
</ul>
</div>
However, <xsl:value-of select="key('fooditem', 1)/Content
only gave me a string of <ul><li>Apples</li><li>Pears</li><li>Oranges</li></ul>
.
The key is defined as <xsl:key name="fooditem" match="FoodItem" use="@ID" />
.
How can I get the individual list tags including their content out of the <![CDATA[]]>
tag?
For an XSLT-1.0 solution, you have to use a two step approach:
One problem is that the CDATA sample is not well-formed XML. So you have to change your input XML (changing the last
<ul>
to</ul>
) to the following:For the first step you can use this (assuming that your XSLT processor does support the disable-output-escaping attribute):
Now you can apply your XSLT template to the output of the above stylesheet.
The result of this transformation should be:
Now, the second step is applying a different XSLT-1.0 stylesheet to this output.
So apply this second XSLT-1.0 stylesheet:
The result of this second step is:
which is as desired.
SOLVED!
With newer versions of XSLT processors (3.0 and above) you can (possibly) do both steps in one stylesheet.
First of all, the
ul
/li
elements are not as nodes in your input XML but rather as escaped markup in a CDATA section. So you would need to parse that markup before being able to transform nodes. With XSLT 3 (as supported by Saxon 9.8 and later or AltovaXML 2017 and later) you can use theparse-xml
orparse-xml-fragment
XPath 3 function to parse a string with an XML document or an XML fragment into nodes.However, at least in your question's sample, the escaped markup is not well-formed XML as it doesn't have a properly closed
ul
element, it is<ul><li>Apples</li><li>Pears</li><li>Oranges</li><ul>
where it should be<ul><li>Apples</li><li>Pears</li><li>Oranges</li></ul>
to be parseable as XML.So depending on the real sample, if that is well-formed, you can use
as shown in https://xsltfiddle.liberty-development.net/3NJ38ZH/1 and get your wanted output