How to process a namespaced XML document using XSLT? - html

I am trying to process an XML file with XSLT to produce a list or table or (eventually) an SQL INSERT command with some of the values. I have been using the example from w3schools http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog.
My XML is very simple and I need to extract just the name and the rate of the hotel:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getHotelsResponse xmlns="http://hotel.booking.vbooking.com">
<getHotelsReturn>
<address>
<number>589-591</number>
<postcode>08014</postcode>
<region>Catalonia</region>
<street>Carrer Vermell</street>
<town>Barcelona</town>
</address>
<name>Downtown Hotel</name>
<rate>235.0</rate>
</getHotelsReturn>
</getHotelsResponse>
</soapenv:Body>
</soapenv:Envelope>
The best XSLT I could build up from the w3schools was this one:
<?xml version="1.0" encoding="utf-8"?>
<!-- Edited by XMLSpyΠ-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/soapenv:Envelope/soapenv:Body/getHotelsResponse">
<html>
<body>
<h2>Hotels in Barcelona</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Hotel name</th>
<th>Rate ($/night)</th>
</tr>
<xsl:for-each select="getHotelsReturn">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="rate"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Which should produce a similar result to what I had in the w3schools example, but it comes back as blank.
Can anyone please explain this? Thanks.

As pointed out by #keshlam, if elements in your input XML have namespaces, you must declare them in your XSLT stylesheet as well.
Find more detail on namespaces in a previous answer of mine.
The gist of the information you find there is: as far as the XSLT processor is concerned, a getHotelsReturn element is entirely different from a vb:getHotelsReturn element.
Stylesheet
<?xml version="1.0" encoding="utf-8"?>
<!-- Edited by XMLSpy?-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:vb="http://hotel.booking.vbooking.com"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
exclude-result-prefixes="soapenv vb">
<xsl:template match="/soapenv:Envelope/soapenv:Body/vb:getHotelsResponse">
<html>
<body>
<h2>Hotels in Barcelona</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Hotel name</th>
<th>Rate ($/night)</th>
</tr>
<xsl:for-each select="vb:getHotelsReturn">
<tr>
<td><xsl:value-of select="vb:name"/></td>
<td><xsl:value-of select="vb:rate"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Output
<html>
<body>
<h2>Hotels in Barcelona</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Hotel name</th>
<th>Rate ($/night)</th>
</tr>
<tr>
<td>Downtown Hotel</td>
<td>235.0</td>
</tr>
</table>
</body>
</html>
Rendered HTML

You can use XPaths like this:
/Product1/Product2/Product3[#ValidYN = 'Y' and #ProductType = 'ABC']
/Product1/Product2/Product3[#ValidYN = 'Y' and #ProductType = 'DEF']
/Product1/Product2/Product3[#ValidYN = 'Y' and #ProductType = 'GHI']
Check this other question How to parse XML using XSLT?

Related

How do I fix this xml and xsl code because it doesn't work

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

XSLT code returns empty rows when converting XML to HTML table

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>

xslt transformation for given xml

This is my xml file for which I am to write an xsl file. Purpose for this xsl is to use for xml to html translation using java xml transform.
I am trying to implement this logic in my xsl file, but unable to get so.
for each loop Id = PO1
if segment Id = PO1
if element Id = PO103
print its value (i.e. CS)
if loop Id = PID
if segment Id = PID
if element Id = PID05
print its value (i.e. BANANAS, ...)
Any help would be appreciated.
Try it this way:
<xsl:for-each select="//loop[#Id='PO1']/segment[#Id='PO1']/element[#Id='PO103']
|
//loop[#Id='PID']/segment[#Id='PID']/element[#Id='PID05'] ">
<!-- whatever "print" means goes here -->
</xsl:for-each>
P.S. Please post your XML as code, not as picture.
Thank you user3016153, with your help I could solve my problem like this :
<?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>HTML generated by XSLT stylesheet from EDI input</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Value</th>
</tr>
<xsl:for-each select="//loop[#Id='PO1']/segment[#Id='PO1']/element[#Id='PO103']
|
//loop[#Id='PID']/segment[#Id='PID']/element[#Id='PID05'] ">
<tr>
<td><xsl:value-of select="#Id"/></td>
<td><xsl:value-of select="."/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Displaying an XML file with XSL to look like HTML

I'm brand new to markup languages and need to display an HTML table, convert it to XML then display it using XSL looking the same as the HTML. Here's a bit of the HTML table:
<table border="1"
cellpadding="5"
summary="Obesity and other statistics">
<tr>
<th>State</th>
<th>Obese adults</th>
<th>Obese children and adolescents</th>
<th>Median Household Income</th>
<th>H.S Graduation rate</th>
</tr>
<tr>
<td>Mississippi</td>
<td>34.4%</td>
<td>17.8%</td>
<td>$36,919</td>
<td>80.4%</td>
</tr>
4 columns, and several rows with 1 title row. Has a summary (not necessary, can be removed for ease), cell padding and a border. Here's the start of the XML table:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="mg.xsl"?>
<data>
<columns>
<State>State</State>
<Obese_adults>Obese adults</Obese_adults>
<Obese_children_and_adolescents>Obese children and adolescents</Obese_children_and_adolescents>
<Median_Household_Income>Median Household Income</Median_Household_Income>
<H_S_Graduation_rate>H.S Graduation rate</H_S_Graduation_rate>
</columns>
<records>
<record>
<State>Mississippi</State>
<Obese_adults>34.4%</Obese_adults>
<Obese_children_and_adolescents>17.8%</Obese_children_and_adolescents>
<Median_Household_Income>$36,919</Median_Household_Income>
<H_S_Graduation_rate>80.4%</H_S_Graduation_rate>
</record>
That was converted following a guideline which may or may not be any good for what I'm trying to do. Couldn't find any clear explanation on what it all does or how to use it with the xsl either.
Here's what I have of the XSL
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2></h2>
<table border="1">
<th>State</th>
<th>Obese adults</th>
<th>Obese children and adolescents</th>
<th>Median Household Income</th>
<th>H.S Graduation rate</th>
</tr>
<xsl:for-each select="data/records/record">
<tr>
<td><xsl:value-of select="State"/></td>
<td><xsl:value-of select="Obese adults"/></td>
<td><xsl:value-of select="Obese children and adolescents"/></td>
<td><xsl:value-of select="Median Household Income"/></td>
<td><xsl:value-of select="H.S Graduation rate"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
which was again formed following a template I found. I have an idea of what it's doing, but not what it's doing wrong and why it isn't working. I would appreciate some help, especially if I am far off of what is the correct way to go about doing this. Thanks
edit: error I'm getting is "Error loading stylesheet: XPath parse failure: operator expected:" by the way.
You have some small mistakes in ur XSLT here is the edited one of yours;
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2></h2>
<table border="1">
<tr>
<th>State</th>
<th>Obese adults</th>
<th>Obese children and adolescents</th>
<th>Median Household Income</th>
<th>H.S Graduation rate</th>
</tr>
<xsl:for-each select="data/records/record">
<tr>
<td><xsl:value-of select="State"/></td>
<td><xsl:value-of select="Obese_adults"/></td>
<td><xsl:value-of select="Obese_children_and_adolescents"/></td>
<td><xsl:value-of select="Median_Household_Income"/></td>
<td><xsl:value-of select="H_S_Graduation_rate"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
the output of this applied to your XML will be;
<html>
<body>
<h2></h2>
<table border="1">
<tr>
<th>State</th>
<th>Obese adults</th>
<th>Obese children and adolescents</th>
<th>Median Household Income</th>
<th>H.S Graduation rate</th>
</tr>
<tr>
<td>Mississippi</td>
<td>34.4%</td>
<td>17.8%</td>
<td>$36,919</td>
<td>80.4%</td>
</tr>
</table>
</body>
</html>

Turn XML data to HTML table with XSLT

I need to be able to turn a flat xml data sets into html tables, and I'm having trouble finding syntax examples that will fit my need. I would like to use one stylesheet that can convert similar looking data sets into html tables with variable columns.
this is a part of my XML File :
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="XSLT_StyleSheet.xsl"?> <Services>
<Service WsdlUrl="http://venus.eas.asu.edu/WSRepository/Services/BasicThreeSvc/Service.svc">
<Name>ServiceName</Name>
<Provider></Provider>
<Category>CatName</Category>
<Operations>
<Operaion>
<Name>HelloWorld</Name>
<MsgIn>elloWorldInputMessage</MsgIn>
<MsgOut>HelloWorldOutputMessage</MsgOut>
</Operaion>
<Operaion>
<Name>OP2name</Name>
<MsgIn>InputMessage</MsgIn>
<MsgOut>OutputMessage</MsgOut>
</Operaion>
<Operaion>
<Name>Op3Name</Name>
<MsgIn>InputMessage</MsgIn>
<MsgOut>OutputMessage</MsgOut>
</Operaion>
</Operations>
this how the HTML table must look Like:
If you did not find examples of transforming XML to HTML with XSLT, then you didn't look very hard. That's one of its primary motivations. Anyway, this should get you started:
<?xml version="1.0" encoding="utf-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|#*"/>
<xsl:template match="/Services">
<html>
<head>
<title>XSLT example</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="Service">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Operations">
<table>
<thead>
<tr>
<td>Name</td>
<td>Description</td>
<td>Type</td>
</tr>
</thead>
<tbody>
<xsl:apply-templates/>
</tbody>
</table>
</xsl:template>
<xsl:template match="Operaion"> <!-- [sic] -->
<xsl:variable name="service" select="ancestor::Service"/>
<tr>
<td><xsl:value-of select="$service/Name"/></td>
<td><xsl:value-of select="Name"/></td>
<td><xsl:value-of select="$service/Category"/></td>
</tr>
</xsl:template>
</xsl:transform>
Output on your (corrected) document (it was missing end tags):
<html>
<head>
<title>XSLT example</title>
</head>
<body>
<table>
<thead>
<tr>
<td>Name</td>
<td>Description</td>
<td>Type</td>
</tr>
</thead>
<tbody>
<tr>
<td>ServiceName</td>
<td>HelloWorld</td>
<td>CatName</td>
</tr>
<tr>
<td>ServiceName</td>
<td>OP2name</td>
<td>CatName</td>
</tr>
<tr>
<td>ServiceName</td>
<td>Op3Name</td>
<td>CatName</td>
</tr>
</tbody>
</table>
</body>
</html>