display xml elements inside xml using xslt - xslt

Ia using XSLT 1.0 and I do have a XML while looks like this
<item name="note"><value><p>Add the &lt;bean&gt; tag pased below to the &lt;beans&gt; element in this file .... </value></item>
I want to display it like this in HTML
Add the <bean> tag passed below to the <beans> element in this file.
Note here that the <p> will be converted to a paragraph tag as I use disable-output-escaping= yes.
This is what I have in my xslt
<xsl:template match="item[#name='note']">
<xsl:value-of select="value" disable-output-escaping="yes" />
</xsl:template>
With this xslt it ignores the bean and beans xml and it does not get displayed in the page. How do I make sure to display it the way I want it?

The problem is that some of your entities have been "double escaped".
&lt;bean&gt; should be <bean>

Related

Parse HTML inside the CDATA text

The data inside CDATA to be parsed as Html.
<?xml version="1.0" encoding="utf-8" ?>
<test>
<test1>
<![CDATA[ <B> Test Data1 </B> ]]>
</test1>
<test2>
<![CDATA[ <B> Test Data2 </B> ]]>
</test2>
<test3>
<![CDATA[ <B> Test Data3 </B> ]]>
</test3>
</test>
From the Above input xml I need the output to be parsed as html.
But I am getting the output as
<B>Test Data1</B>
<B>Test Data2</B>
<B>Test Data3</B>
But the actual output I need the text to be in bold.
**Test Data1
Test Data2
Test Data3**
The input is coming from external system.We could not change the text inside CDATA
Parsing as HTML is only possible with an extension function (or with XSLT 2.0 and an HTML parser written in XSLT 2.0) but if you want to create HTML output and want to output the contents of the testX elements as HTML then you can do that with e.g.
<xsl:template match="test/*[starts-with(local-name(), 'test')]">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
Note however that disable-output-escaping is an optional serialization feature not supported by all XSLT processors in all use cases. For instance with client-side XSLT in Mozilla browsers it is not supported.
If your have to stay with XSLT 1.0 you have to to run two transformation passes.
First one to copy your xml but remove the CDTA by generate the content with disable-output-escaping="yes" (See answer from #Martin Honnen)
In second path you can access the html part.
But this may be only possible if the html part follow the roles for well formatted xml (xhtml). If not perhaps a input switch as in xsltproc may help to work with html e.g.:
--html: the input document is(are) an HTML file(s)
See also: Convert an xml element whose content is inside CDATA

How to prevent self closing tags as well empty tags after transforming

I have in an input file:
<a></a>
<b/>
<c>text</c>
I need to converting this to string. Using transformer I am getting below output:
<a/> <!-- Empty tags should not collapse-->
<b/>
<c>text</c>
If I use xslt and output method is "HTML", I get the below output:
<a></a> <!-- This is as expected-->
<b></b> <!-- This is not expected-->
<c>text</c>
I want the structure same as in input file. It is required in my application since I need to calculate index and it will be very difficult to change the index calution logic.
What would be the correct XSLT to use?
What XSLT processor? XSLT is merely a language to transform xml so "html output" is dependent on the processor.
I'm going to guess this first solution is too simple for you but i've had to use this to avoid processing raw html
<xsl:copy-of select="child::node()" />
as this should clone the raw input.
In my case, I have used the following to extract all nodes that had the raw attribute:
<xsl:for-each select="xmlData//node()[#raw]">
<xsl:copy-of select="child::node()" />
</xsl:for-each>
Other options:
2) Add an attribute to each empty node depending on what you want it to do later ie role="long", role="short-hand".
3)
Loop through each node (xsl:for-each)
<xsl:choose>
<xsl:when test="string-length(.)=0"> <!-- There is no child-->
<xsl:copy-of select="node()" />
</xsl:when>
<xsl:otherwise>
...whatever normal processing you have
</xsl:otherwise>
4) Redefine your problem. Both are valid XHTML/XML, so perhaps your problem can be reframed or fixed elsewhere.
Either way, you may want to add more information in your question so that we can reproduce your problem and test it locally.
P.S. Too much text/code to put in a comment, but that's where this would belong.
A possible alternative is to use disable-output-escaping like this:
<xsl:text disable-output-escaping="yes"><a></a></xsl:text>
But I understand that this is a dirty solution...

Need to validate a string, whether it contains html or xml using xslt

I have an xsl:variable whose contents might be HTML or XML or binary.
I'm displaying the value of the variable in a textarea in a html page.
If the variable contains HTML or XML data, it is displayed unformatted in the textarea.
<xsl:variable name="outputString">
//html or xml or binary data goes in here
</xsl:variable>
<xsl:template match="/">
<html>
<body>
<textarea name="output" cols="20" rows="20">
<xsl:value-of select="$outputString" />
</textarea>
</body>
</html>
</xsl:template>
All I need is to display the contents of the variable in a formatted way inside the textarea if the contents are either HTML or XML.
You'll need processor extensions to do this job, so the answer depends on which XSLT processor you are using.
Well I would need to try it out, but I believe you could do the following
<xsl:if test="fn:contains($outputString, '<(.*)>.*<\1>')>
</xsl:if>
or in your case I would rather use the choose tag.
The fn:contains() is for XSLT 2.0 and the part I'm not sure is weather it will accept the regex in that format. even more because some places use $1 instead of \1 for referencing the group value.
If you are referencing a XML or HTML that would detect it though.

How to access variable in CDATA from XSLT?

I am using XSLT Transformation and need to put some data in CDATA section and that value is present in a variable.
Query: How to access variable in CDATA ?
Sample Given Below:
<xsl:attribute name ="attributeName">
<![CDATA[
I need to access some variable here like
*<xsl:value-of select ="$AnyVarible"/>*
]]>
</xsl:attribute>
How can I use varibale in CDATA ?
Note: I can not use --> <![CDATA[<xsl:value-of select ="$AnyVarible"/>]]>
Thanks in advance.
I got the solution for this...FYI for everyone...
<xsl:text
disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select ="$AnyVarible"/>
<xsl:text
disable-output-escaping="yes">]]></xsl:text>
CDATA is just text like any other element contents...
But using the xsl:output element you should be able to specify which elements are to be written as CDATA with the cdata-section-elements attribute.
EDIT:
Now that there is a valid sample, I guess you mean this:
<xsl:attribute name ="attributeName">
<![CDATA[
I need to access some variable here like
*]]><xsl:value-of select ="$AnyVarible"/><![CDATA[*
]]>
</xsl:attribute>
If you want to include CDATA sections in your output, you should use the cdata-section-elements atribute of xsl:output. This is a list of element names. Any such elements will have their text content wrapped in CDATA.
<xsl:output cdata-section-elements ="foo" />
<foo>
<xsl:value-of select="$bar' />
</foo>

XSL variable number of child nodes

I've got some XML elements with a number attached as more are available.
Such as this:
<Images>
<Image1>C:\Path\To\AnImage</Image1>
<Image2>C:\Path\To\AnotherImage</Image2>
</Images>
The amount of Images in each XML doc is variable. How can I make sure that my XSL file will show all elements inside the tag?
I also want to put each of the strings inside each ImageX tag inside a Img src="stringfromxmlelement" with XSL? Is this possible?
Tony
<xsl:template match="Images/*[starts-with(name(),'Image']">
<img src="{.}" />
</xsl:template>
BTW, perhaps you can't change the XML tag names, but it would better to name the inner tags as Image rather than ImageX, which is probably unneccesary.
I'd try something along these lines:
<xsl:template match="Images">
<xsl:for-each select="*">
<img src="{text()}" />
</xsl:for-each>
</xsl:template>