How to access elements of a subelement using XSLT? - html

I have the following XML code:
http://codeshare.io/MQyQu
and am using the following XSLT code:
http://codeshare.io/LWl6g
in coordination with the W3 Schools "Tryit Editor" tool for XSLT. I can't link it due to reputation.
My problem is that the XSLT does not parse all the elements (semester elements within a catalog element, and class elements within a semester element).
The W3 schools example of XSLT uses only one subelement, and I'm at a loss for what to do for two subelements.
My understanding is that the first
<xsl:for-each select="catalog/semester">
will loop semester elements in the catalog elements.
Within the loop, I have a HTML table where I want to output the information of the class element, that is a subelement of semester. I think nesting this code in the original for-each loop should output the text for each element for each class in the table:
<xsl:for-each select="class">
<td><xsl:value-of select="dept"/></td>
<td><xsl:value-of select="number"/></td>
<td><xsl:value-of select="title"/></td>
</xsl:for-each>
In the HTML table, only the text, "CIT", of the first subelement, dept, of the element class is displayed.
I deduct that the for-each loop isn't parsing. If that is the reason, why?
If my deduction on why the XSLT code isn't reading the XML code how I want it is incorrect, what is the correct reason and how can I fix it?

There are several problems here...
Your input XML isn't well formed - there are tags that begin <number> but aren't closed (it seems like the tag that ends with </dept> is meant to close it).
Your input XML contains unescaped ampersands. Replace & with &
Your Stylesheet is invalid because it's missing a </table> tag. You need to add it in.
Your inner for-each loop should probably have <tr> and </tr> tags around the <td>...</td> nodes.
Here's an XSLTransform with all of these problems addressed (and I added an output instruction so that XSLTransform can show it as HTML in the window):
http://xsltransform.net/94rmq66
So the bottom line is that you're right, the XSLT parser can't read the XML because it's malformed XML. The fact that it's doing anything at all with your input is pretty bad, and another reason not to use the W3Schools XSLT tools.

Related

Generation of XSLT From XML

I have an XML File with very large content.
I had an xsd file for that xml file.
For example : Please visit this link
XML CONTENT : http://formalmind.com/sites/default/files/blog/manual-testing.reqif
XSD For that XML : https://www.omg.org/spec/ReqIF/20110401/reqif.xsd
I need to display that xml in HTML page. For that i need XSLT.
Is it possible to generate XSLT for the given XML Automatically ? or is there is any other way to display in html Page?
Html Result Should be like
HTML_OUTPUT_IMAGE
Thanks
Sivabalakrishnan
Yes, this is possible, but it's not clear that it's a useful approach. What information in the schema do you intend to use to generate your XSLT? You need to give some examples of constructs that you find in the schema, and the resulting XSLT rules that you want to generate.
There are two other options you should consider:
(a) writing a completely generic XSLT stylesheet, that handles any document regardless of its schema. For example, it could contain rules like this:
<xsl:template match="*[count(*)>1 and count(*)=count(distinct-values(*/node-name())]">
<table>
<xsl:for-each select="*">
<tr>
<td><xsl:value-of select="name()"/></td>
<td><xsl:apply-templates/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
This rule says that if you encounter an element with 2 or more element children, and all the children have distinct names, then display a table containing the element names in one column and their values in another.
(b) writing a generic schema-aware (XSLT 2.0) stylesheet that handles any input document, but uses schema information from the type annotations on validated nodes to decide what output to generate. For example you might have a rule like this:
<xsl:template match="#*[data(.) instance of xs:decimal]">
<xsl:value-of select="format-number(., '#,00', 'continental')"/>
</xsl:template>
which causes all decimal attribute values to be displayed using a format such as 3,14.

Styling inline XML tags with XSLT

This is a similar question to Style inline text along with nested tags with XSLT, but I can't comment to get clarification, so I will elaborate my specific scenario here. I basically have an XML document with the following structure:
<book>
<chapter>
<para>This is some text about <place>New York</place></para>
</chapter>
</book>
I am using XSLT to output XHTML from my XML file, and I want to be able to put span tags or something around the content in the place tag in the example above. The purpose is so that I can style these segments of text with CSS. Following the example I referenced above, I added this:
<xsl:template match="book/chapter/para/place">
<span class="place">
<xsl:apply-templates/>
</span>
</xsl:template>
When I load the XML document in the browser I get the error: "Error loading stylesheet: Parsing an XSLT stylesheet failed." (the stylesheet was loading properly before I added this part)
I'm assuming I lack some basic understanding of how xsl:apply-templates should be used. I would appreciate it if someone could point me in the direction of figuring this out.
Thanks!
The match:
<xsl:template match="book/chapter/para/">
applies templates to all children of the place element, rather than place itself.
Use select within apply-templates instead:
<xsl:template match="/">
<xsl:apply-templates select="book/chapter/para/place"/>
</xsl:template>
In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node, including text nodes.
A select attribute can be used to process nodes selected by an expression instead of processing all children. The value of the select attribute is an expression. The expression must evaluate to a node-set.
References
XSLT 1.0 Specification

HTML within XML is not displayed properly in the output after conversion using XSLT

I've an XML file generated as an output of a Java program. This contains some text in the form of html in which the tags are written with < and > instead of < and > respectively. I want to convert this xml to html where in the inner html is also processed. For example:
My xml snippet:
<company>
<companyEnhancement>
Rank: -1</br> Other Links</br>http://www.gehealthcare.com/</br>
</companyEnhancement>
</company>
And, my xslt stylesheet has this part to parse it:
<td>
<xsl:value-of select="companyEnhancement"/>
</td>
But the html output on the browser, has this data as it is within a table cell:
Rank: -1 </br> Other Links</br>http://www.gehealthcare.com/</br>
I read through the links here, but I am not able to understand what exactly I should do in the stylesheet.
Please help me out. I am very new to xslt, so please excuse if it is a silly question.
Thanks
You say you have HTML in there but </br> is not HTML syntax, that would be <br> or perhaps for XHTML <br />.
If you really have escaped HTML and want to output that then you can try
<xsl:value-of select="companyEnhancement" disable-output-escaping="yes"/>
but that is only going to help if your XSLT processor serializes the result tree. Firefox for instance does not do that and does not support disable-output-escaping.

Import an HTML table using XSL

I have constructed an XSL file that parses an XML formatted log and generates an HTML page with information from the log. In this same XSL file, I am attempting to use XSL to pull in an external HTML file that contains a table that I want to display. As it stands, I can display the entire page that contains the table, but am unable to isolate the table. How can this be done? Currently, I can pull in the entire page using the following code:
<xsl:copy-of select="document($tablePageUrl)" />
However, I don't understand how to traverse the HTML body and pull out a copy of the table. An example of how the HTML document is formatted (the document is proper XML, but not proper HTML):
<html>
<head>
</head>
<body>
<table>
Table Contents
</table>
</body>
</html>
Sounds like you want to use XPath to select a particular element in the document.
Try something like:
<xsl:copy-of select="document($tablePageUrl)/html/body/table" />
From comments:
I had tried using XPath but was using
incorrect syntax
From http://www.w3.org/TR/xpath/#node-sets
The / and // operators compose an
expression and a relative location
path. It is an error if the expression
does not evaluate to a node-set. The
/ operator does composition in the
same way as when / is used in a
location path
In particular, this syntax:
document($tablePageUrl)/html/body/table
Following the production:
PathExpr ::= FilterExpr '/' RelativeLocationPath
FilterExpr ::= PrimaryExpr
PrimaryExpr ::= FunctionCall
Check to see whether the HTML is in a namespace. (Look for a telltale xmlns="....".) Your sample isn't in a namespace, but from experience, if people don't realise that namespaces matter, they often remove the namespace declaration when posting samples. If the elements are in a namespace, then the XPath expression needs to use prefixed names to select them.
<xsl:variable name="source-html" select="document('url')" />
<xsl:value-of select="$source-html//table" />

XSLT string with HTML entities - How can I get it to render as HTML?

I'm completely new to using XSL, so if there's any information that I'm neglecting to include, just let me know.
I have a string in my XSLT file that I can display like this:
<xsl:value-of select="#Description/>
and it shows up, rendered in a browser like:
<div>I can't do anything about the html entities existing in the text.</div> <div>This includes quotes, like "Hello World" and sometimes whitespaces. </div>
What can I do to get this string rendered as html, so that <div></div> results in newlines, " gives me ", and gives me a space?
I could elaborate on things I've already tried that haven't worked, but I don't know if that's relevant.
I think you want to set the following attribute as so:
<xsl:value-of select="#Description" disable-output-escaping="yes"/>
Why do you need to have entities output? To the browser is the same as   -- in both cases it will display a non-breaking space.
There is a feature in XSLT 2.0 called character-maps, that provide this functionality, if really needed. It is an XSLT best practice to try not to use DOE, unless absolutely necessary.
Also, DOE is not a mandatory feature of XSLT and some XSLT processors may not implement it. This means that an XSLT application that uses DOE is generally not portable across different XSLT processors.
The reason divs in HTML get an endline is completely different and related to the CSS boxmodel. Most browsers apply the style:
div {display:block;}
In lieu of the standard display:inline;. However, they only do that to divs in the XHTML namespace. You need to output divs to the XHTML namespace to faciliate that. Bind the XHTML namespace to the prefix xhtml at the top of your document like so:
<xsl:stylesheet xmnls:xhtml="http://www.w3.org/1999/xhtml" ... >
And then output the divs as <xhtml:div> ... </xhtml:div> most browsers would recognise the div to be in the XHTML namespace (http://www.w3.org/1999/xhtml) and apply the block style.