I have a xml file with one of the nodes as:
<test-case time="0.077" name="TestingNunit.NUnitTestClass.NunitTestMethod1" asserts="1" success="False" result="Failure" executed="True">
<failure>
<message>
<![CDATA[ Expected: not 3.0d But was: 3.0d ]]>
</message>
<stack-trace>
<![CDATA[at TestingNunit.NUnitTestClass.NunitTestMethod1() in z:\UnitTestingSample\UIAutomation\TestingNunit\UnitTest1.cs:line 12 ]]>
</stack-trace>
</failure>
</test-case>
<test-case time="0.003" name="TestingNunit.NUnitTestClass.NunitTestMethod2" asserts="2" success="False" result="Failure" executed="True">
<failure>
<message>
<![CDATA[ Expected: 2.0d But was: 3.0d ]]>
</message>
<stack-trace>
<![CDATA[at TestingNunit.NUnitTestClass.NunitTestMethod2() in z:\UnitTestingSample\UIAutomation\TestingNunit\UnitTest1.cs:line 21 ]]>
</stack-trace>
</failure>
Now I want to read the data of all CDATA's". I am trying to generate a html file using XSL for which I need this data? I am able to generate data for normal nodes and their attributes but for a node written in this way I am unable to figure out a way to read it. This is my xsl file foreach loop
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th>Test Method</th>
<th>Execution Time</th>
<th>Asserts Performed</th>
<th>Success</th>
<th>Result</th>
<th>Executed</th>
<th>Failure Message</th>
<th>Stack Trace</th>
</tr>
<xsl:for-each select="test-results/test-suite/results/test-suite/results/test-suite/results/test-case">
<tr>
<td><xsl:value-of select="#name"/></td>
<td><xsl:value-of select="#time"/></td>
<td><xsl:value-of select="#asserts"/></td>
<td><xsl:value-of select="#success"/></td>
<td><xsl:value-of select="#result"/></td>
<td><xsl:value-of select="#executed"/></td>
<td><xsl:value-of select="//failure/message/text()" disable-output-escaping="no"/></td>
<td><xsl:value-of select="//failure/stack-trace/text()" disable-output-escaping="no"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
To read CDATAs (and then transform them) use the text() function in your XPath.
//test-case/failure/message/text()
//test-case/failure/stack-trace/text()
Try select="./failure/message/text()" instead of select="//failure/message/text()" (mind the ./ at the beginning).
Doing this the XPath relates to the node that is currently selected by the for-each loop. When using // it will select all nodes from the document ignoring the currently selected node. Imagine this like a lscommand on Linux: ls /* will select the top level elements regardless of your current work directory, while ls ./* will select the child elements of your current work directory.
Related
First attempt to code xml and use xsl for html output.
I took the W3 examples and modified them for my needs but I've missed something as looking at the xml in a browser does work correctly. None of the html code shows in the browser but the items info from the xml shows as long list.
What shows in browser:
SCALARADD Image1inSCALARADD Add one value to an image. A B A same as B allowed redLevel, greenLevel, blueLevel TRIMFILL Image1inTRIMFILL Trim an image and fill the trim area. A B A same as B allowed trimTopIndex, trimBottomIndex, trimLeftIndex, trimRightIndex fillRedLevel, fillGreenLevel, fillBlueLevel
Here is the xml file:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="routines.xsl"?>
<family>
<Image1in>
<routine>SCALARADD</routine>
<symbolic> Image1inSCALARADD </symbolic>
<operation> Add one value to an image. </operation>
<inputLayer1> A </inputLayer1>
<inputLayer2></inputLayer2>
<outputLayer1> B </outputLayer1>
<commentLayer> A same as B allowed </commentLayer>
<inputLong></inputLong>
<inputDouble> redLevel, greenLevel, blueLevel </inputDouble>
<outputLong></outputLong>
<outputDouble></outputDouble>
<comment> </comment>
</Image1in>
<Image1in>
<routine>TRIMFILL</routine>
<symbolic> Image1inTRIMFILL </symbolic>
<operation> Trim an image and fill the trim area. </operation>
<inputLayer1> A </inputLayer1>
<inputLayer2></inputLayer2>
<outputLayer1> B </outputLayer1>
<commentLayer> A same as B allowed </commentLayer>
<inputLong> trimTopIndex, trimBottomIndex, trimLeftIndex, trimRightIndex </inputLong>
<inputDouble> fillRedLevel, fillGreenLevel, fillBlueLevel </inputDouble>
<outputLong></outputLong>
<outputDouble></outputDouble>
<comment> </comment>
</Image1in>
</family>
Here is the xsl file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Routines</h2>
<table border="2">
<tr bgcolor="#7f7f7f">
<td style="text-align:left">Title</td>
<td style="text-align:left">Symbol</td>
<td style="text-align:left">Operation</td>
<td style="text-align:left">Input Layer 1</td>
</tr>
<xsl:for-each select="family/Image1In">
<xsl:sort select="routine"/>
<tr>
<td><xsl:value-of select="routine"/></td>
<td><xsl:value-of select="symbolic"/></td>
<td><xsl:value-of select="operation"/></td>
<td><xsl:value-of select="inputLayer1"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
I appreciate any help someone can share. Spent whole weekend try to fix.
Regards,
RONC
A browser is not a good environment for testing XSLT. As it happens, your XSLT has a mistake of using:
<xsl:for-each select="family/Image1In">
instead of:
<xsl:for-each select="family/Image1in">
XML is case-sensitive, and your expression selects nothing.
However, you should still be seeing the header row of the table. What you see instead - the raw text of of the XML - suggests that your browser is applying the "same origin" security rule and blocking the request for the stylesheet.
You can try this code <xsl:for-each select="family/Image1in"> insted of <xsl:for-each select="family/Image1In"> Or if you want to remove both leading and trailing space remove use normalize-space().
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Routines</h2>
<table border="2">
<tr bgcolor="#7f7f7f">
<td style="text-align:left">Title</td>
<td style="text-align:left">Symbol</td>
<td style="text-align:left">Operation</td>
<td style="text-align:left">Input Layer 1</td>
</tr>
<xsl:for-each select="family/Image1in">
<xsl:sort select="routine"/>
<tr>
<td><xsl:value-of select="normalize-space(routine)"/></td>
<td><xsl:value-of select="normalize-space(symbolic)"/></td>
<td><xsl:value-of select="normalize-space(operation)"/></td>
<td><xsl:value-of select="normalize-space(inputLayer1)"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
DEMO: https://xsltfiddle.liberty-development.net/3NSSEv5
I am trying to make a URL in my XML file clickable. Below is my XML and XSL files which work fine together.
I've tried using XLink and href in XML file but it didn't work.
How do I make my URL in the XML file clickable?
XML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="file.xsl" ?>
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="1.xsl" ?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Johnny</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<url>http://www.yahoo.com</url>
</cd>
</catalog>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>XSL</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
<th style="text-align:left">Country</th>
<th style="text-align:left">Company</th>
<th style="text-align:left">Price</th>
<th style="text-align:left">URL</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<td><xsl:value-of select="country"/></td>
<td><xsl:value-of select="company"/></td>
<td><xsl:value-of select="price"/></td>
<td><xsl:value-of select="url"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
Before writing any XSLT, you should really know what output you want. And to make a link clickable in HTML you can do this...
http://www.yahoo.com
So, in your XSLT, instead of doing this....
<td><xsl:value-of select="url"/></td>
Do this...
<td>
<a href="{url}">
<xsl:value-of select="url"/>
</a>
</td>
Note the use of curly braces in the href attribute. This is known as an Attribute Value Template. The curly braces indicate an expression to be evualated, rather than output literally.
I'm writing an XSL transformer to convert XML to HTML. Here's my gun.xml:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="guns.xslt"?>
<guns xsi:noNamespaceSchemaLocation="guns2.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<gun>
<model>revolver</model>
<handy>1</handy>
<origin>Britain</origin>
<ttc>20mm</ttc>
</gun>
</guns>
And guns.xslt here:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
<h2>Gun Collection</h2>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Model</th>
<th>Origin</th>
<th>TTC</th>
</tr>
<xsl:for-each select="guns/gun">
<tr>
<td><xsl:value-of select = "model"/></td>
<td><xsl:value-of select = "handy"/></td>
<td><xsl:value-of select = "origin"/></td>
<td><xsl:value-of select = "ttc"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Both files are located in the same package, but XPAth doesn't recognize "guns/gun" in for-each block. What am I missing?
You have declared in xml-stylesheet - type as "text/xsl", please change file extension from "guns.xslt" to "guns.xsl" and also change in your XML as below:
<?xml-stylesheet type="text/xsl" href="guns.xsl"?>
Then your result will be as below:
I am trying to convert an XML document to HTML using XSLT 1.0. I aim to display the XML rows in an HTML table. But my XSLT code returns empty rows in the HTML table. Here's what my XML looks like:
<?xml version="1.0" encoding="UTF-8"?>
<people>
<person id="ABCDE1234" firstname="John" lastname="Lewis" sex="male"/>
<person id="XYZWU6789" firstname="Marie" lastname="Claire" sex="female"/>
</people>
Here's my XSLT code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>XML to HTML using XSLT</title>
</head>
<body>
<table border="1" >
<tr>
<th>id</th>
<th>firstname</th>
<th>lastname</th>
<th>sex</th>
</tr>
<xsl:for-each select="people/person">
<tr>
<td><xsl:value-of select="id"/></td>
<td><xsl:value-of select="firstname"/></td>
<td><xsl:value-of select="lastname"/></td>
<td><xsl:value-of select="sex"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
However, my XSLT code runs properly when I reformat the XML file as follows:
<?xml version="1.0" encoding="UTF-8"?>
<people>
<person>
<id>ABCDE1234</id>
<firstname>John</firstname>
<lastname>Lewis</lastname>
<sex>Male</sex>
</person>
<person>
<id>XYZWU6789</id>
<firstname>Mary</firstname>
<lastname>Claire</lastname>
<sex>Female</sex>
</person>
</people>
Why is this happening? Any ideas?
Just add the # sign so that the values will recognize as attributes.
<td><xsl:value-of select="#id"/></td>
<td><xsl:value-of select="#firstname"/></td>
<td><xsl:value-of select="#lastname"/></td>
<td><xsl:value-of select="#sex"/></td>
When i open the xml file with mozilla i get this error:
XML Parsing Error: no element found
Location: file:///D:/PTI/xsl.xsl
Line Number 26, Column 8:
-------^
How can i fix that ?
XML Code:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<books name="List">
<book>
<title>Don Quixote</title>
<author>Miguel de Cervantes</author>
<theme>Adventure</theme>
<price>$120</price>
<year>1605</year>
</book>
<book>
<title>A Tale Of Two Cities</title>
<author>Charles Dickens</author>
<theme>History</theme>
<price>$75</price>
<year>1859</year>
</book>
</books>
XSL Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Book Catalog</h2>
<table border="1">
<tr>
<th>Title</th>
<th>Author</th>
<th>Theme</th>
<th>Price</th>
<th>Year</th>
</tr>
<xsl:for-each select="books/book">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="author"/></td>
<td><xsl:value-of select="theme"/></td>
<td><xsl:value-of select="price"/></td>
<td><xsl:value-of select="year"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
Unless you forget to include a part of your XSLT file you're missing some closing tags (template and stylesheet). Just add them to the end of your xsl.xsl document:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
...your stuff here...
</html>
</xsl:template>
</xsl:stylesheet>