How best open xml, parse with xslt and show result in browser - html

I am currently studying ways to present transformed xml files in browsers. My experience with this is minimal, so a number of questions pop up.
I have a transformation test.xslt which transforms input xml to html, and an input file test.xml containing
<?xml version="1.0" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="test.xslt" ?>
<root>...</root>
which, when opened in IE9, neatly displays the transformed xml contained above in the root element.
Question 1
Is there a processing instruction or similar available to include the source xml into the xml to be opened, somewhat like the following:
<?xml version="1.0" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="test.xslt" ?>
<... instruction to include source file data.xml>
Question 2
The file opened has extension xml. Is there a way to change file contents so it is valid html, allowing the file to be saved with extension html, so that when opened, the default browser will be selected (simply changing extension to html obviously does not have the desired effect so some structural change is necessary) ?
Question 3
My goal is to query a db to get the data to be parsed by the xslt code. What is the best way to do this (no problem if this includes javascript)?
Question 4
Standard db utilities may export query results in attribute-centered fashion (column names and values being represented as attribute names and values). This may involve pre-parsing the xml from db in order to convert it to parent-child fashion (columns as children instead of attributes). What is the best way to do this pre-parsing (note: I already have the xslt for this; I wonder about the data flow and when/how to run two xslt's in sequence) and then apply test.xslt (preferably without saving intermediate xml result files on the server)?
Question 5
When I open above xml in IE9, this works fine as said. But opening it in Firefox errors (RTF issue, apparently I need to use Firefox's node-set function but I still have to discover which namespace that has), and Opera/Chrome/Safari do not show any content. What exactly are the prerequisites for the various browsers where can I find more information on this?

Q1 If you start by serving an html file which then accesses the xml and xslt via javascript it naturally has access to both the input and the output of the xslt. If you are serving the xml and initiating the transformation using xml-stylesheet pi, then perhaps the best thing to do (depending on what you want to do) is to stuff the original source into the output, then javascript in the generated page can access it if needed, eg
<xsl:template matcj="whatever">
<html>
<head>
<script id="source" type="x-xml-spurce">
<xsl:copy-of select="/"/>
</script>
.... whatever you were going to do
then if you need to access the source in response to a user action on the page, a script can retrieve the script with id source and do whatever is needed. (If there is a possibility of the the source including the string you have to code it a bit more defensively).
Q2 If you want to use the xml-stylesheet API then you have to serve it as xml. However you can instead just serve html and then access the xml and xslt from within a script in the html page using the browsers javascip xslt api. as noted above that is more flexible than the xml-stylesheet mechanism.
Q3 pass
Q4 If you are accessing the xslt from javascript then it is easy to chain the output of one to the input of another without writing back to the server as you just have access to the result as a DOM node (or string, depending)

Answer to question 5: Firefox/Mozilla, Opera, Safari, Chrome all support the EXSLT node-set extension function in the namespace http://exslt.org/common, for IE and MSXML you can use script (imported) inside the XSLT stylesheet to allow it to support that namespace too, see http://dpcarlisle.blogspot.de/2007/05/exslt-node-set-function.html. That way inside the main stylesheet where you need to use the node-set function you don't need to write different code to cater for the different namespaces.

Related

Adding an invisible document name in XSLT or HTML

I have this XSLT document that has a file name. However for archiving purposes we want the file name to be displayed somewhere else within the code.
Now I used to do this like this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
sample-xml=".\DOCUMENTNAME.xml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office">
However we want to get rid of this solution due to new working methods. Now I was wondering if I could place this (literally just the word DOCUMENTNAME) somewhere within the XSL or within the HTML wrapped within it, in a way that it is not visible.
We add this code to a database, through a validator that looks for the documentname and checks for a match. And as only the contents of the code is placed on the database its easier to check back from the database what documentname was uploaded. However this documentname should not be visible in an HTML output.
Maybe add a processing instruction or comment somewhere in the XSLT.
Like:
<?DOCUMENTNAME?>
or:
<!--DOCUMENTNAME-->
They're not invisible, but they definitely won't be included in the output.
Not visible to whom?
Your current solution (with sample-xml) is not valid XSLT: unknown attributes on an XSLT element should be rejected by the processor unless they are in a namespace of their own.
The cleanest way to do this is probably a top-level element (a child of xsl:stylesheet) in a private namespace:
<my:document-name xmlns:my="http://my.company.com/ns/document-id">document.xml</my:document-name>
I don't know if that meets your criteria of being "not visible". It certainly wouldn't be visible in the output of the stylesheet.

Is it possible to make a selectable drop down menu using data from an XML file?

I'm trying to create a directory for an address book, and I was wondering if it would be possible to create a selectable drop down menu that would pull the contact data from an XML file. The ideal way I would want it is to have all of the names of the contacts in the drop down menu, and when one is selected the rest of the information would pop up above the drop down, such as Address, Phone Number, and Email.
Either use a server-side language such as PHP to extract the data from the XML and insert it into the HTML document, or use AJAX to pull the XML file to the client then use JavaScript to process it and insert it into the DOM.
There should be libraries/frameworks/plugins/whatever available to parse XML using whatever language you need, if you know how to insert stuff into the HTML document (in the case of PHP) or into the DOM (in the case of JavaScript), you can do this easy.
From what I understand you have an XML document. Using XSLT you create an XHTML file from your XML and that you can display in your browser (XHTML is HTML that is conform to XML rules).
If that is the case then, yes, you can make links using XSLT. But the data needs to be in your XML source file and not in some database.
There is an article that describes it: http://www.ibm.com/developerworks/xml/library/x-tipxslt/index.html
You could attach an XSL to the XML using something like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
... actual XML content...
If applying the XSL on the XML outputs an HTML page with JavaScript, you can get the actual result.
Outputting JavaScript is a bit of a pain because of character escaping but it can be done.

XHTML rendering timeline different from HTML in WebKit?

I'm working on a project where we went from XHTML to HTML back to XHTML and there are some definite behavioral changes going back with regards to the page rendering before the CSS loads and scripts that read styles reading them before the CSS loads. Can anyone shed some light on why the following is happening and what can be done about it?
Basically, I have a page with the following structure:
<body>
<!-- Content from Source A -->
<link href="http://a.example.com/style.css" />
<header>...</header>
<!-- Content from Source B -->
<link href="http://b.example.com/style.css" />
<div>...</div>
<!-- Content from Source A -->
<footer>...</footer>
<script src="http://a.example.com/script.js">
/* e.g. */
alert($('header').offset().height);
</script>
</body>
When we were in HTML rendering mode, the page blocks rendering at expected points. When we hit the Source A CSS, rendering pauses (blank screen); when we hit the Source B CSS, rendering pauses (header is visible). When we hit the Source A JavaScript, rendering pauses (full page shown) and the script reads element styles from their rendered state. (In reality, of course, WebKit doesn't stop parsing the DOM or executing JavaScript while the CSS loads, but it does halt execution at the first point where the script needs to read a style.)
When we are in XHTML mode, the page doesn't halt rendering at all and will render the entire page completely unstyled. After that, it appears to process the scripts and stylesheets in the order loaded, or rather it executes the scripts in order but doesn't wait for the stylesheet to load before executing a loaded script. This means that the page will render three times (unformatted, with one stylesheet, and with two stylesheets) and the script may infer completely inaccurate values for element sizes.
Can someone shed light on this? This is happening in all WebKit browsers I've tested, including Chrome 17, Mobile Safari 5, and Android Browser 2.1. Is there any way to ensure HTML render ordering without resorting to the text/html mime type?
WebKit uses libxml2 to handle XML, which sends the parsed XHTML back to WebCore and JavaScriptCore to do the CSS rendering and JavaScript execution.
Stylesheet and script tags link to what's called an external entity in XML terminology. That means they are processed last. The XML spec says:
Except when standalone="yes", they must not process entity declarations or attribute-list declarations encountered after a reference to a parameter entity that is not read, since the entity may have contained overriding declarations; when standalone="yes", processors must process these declarations.
Since standalone="yes" specifies that the XML document should be validated by a DTD, this triggers a different processing model.
Link tags are handled differently than xml-stylesheet processing-instructions. The XML stylesheet spec says:
Any links to style sheets that are specified externally to the document (e.g. Link headers in some versions of HTTP [RFC2068]) are considered to create associations that occur before the associations specified by the xml-stylesheet processing instructions. The application is responsible for taking all associations and determining how, if at all, their order affects its processing.
Try commenting out the script tags and converting the link tags xml-stylesheet instructions. Also, try adding standalone="yes" to the XML declaration:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet href="foo.css"?>
In addition, the use of special characters, entities, and XSLT can further complicate the picture, since the processing model differs between HTML and an XML dialect like XHTML:
The range of allowed chars in XML is defined by the XML spec, and
the range is fully checked by libxml2. Not a concern, unless you parse
this for example with an HTML parser and give the preparsed tree to
libxml2 to serialize back. I hope you're not doing this as XSLT is
an XML language and must be parsed by an XML parser.
References
libxml2 Paser Internals
blink-dev => Intent to Deprecate and Remove: XSLT
blink-dev => Security: libxml2 growBuffer integer overflow on 64-bit machines
blink-dev => Stack-buffer-overflow in xmlSerializeHexCharRef
Webkit Title Index

XML -> XSL -> HTML edit file, and SAVE changes in xml WITHOUT asp

I have an XML file that I've transformed with xsl and loaded into a browser as html. That html is editable using a rich text editor by the user. When they're done I need to transform their html edits back to the original xml document.
One solution I've found is using ASP: http://www.w3schools.com/xsl/xsl_editxml.asp
But I'm using Apache and I don't have ASP installed, and I'm wondering if there is an easier/better way to do this without using ASP.
Or is ASP the only way?
Thanks =)
The solutiton that you found doesn't do what you describe. It only presents the data from the XML as a form, and lets the user edit the values. That's not very complex, and you can do that using pretty much any other server side language, like PHP for example.
What you describe, on the other hand, is quite complex. It involves examining the XSL and the HTML to identify the parts of the HTML code that was created using specific XML data, so that changes can be reflected back. That's not something that is done with a simple ASP script like that.
If you design an XSL transformation for both directions, XML to HTML and HTML to XML, comparing the source XML and resulting user XML should be a much easier problem to solve.

How to show XSL-converted XML as a part of an HTML page?

Can I embed an XML file in HTML without using iFrames?
I want to show XSL-transformed XML(which, is HTML as a result of transformation) as a part of my HTML document. Hope this makes it clearer.
If my description of problem is unclear, please tell me and I will try to explain it more.
You can easily use browser based XSL transformation routines to convert an XML string into an XMLDocument or HTML output that can then be applied into any page element.
The steps could be briefly summarized as:
Load an XML string from a resource (or as the result of an AJAX hit).
Load the XML document into an Xml document object (code differs for Browsers - IE uses the ActiveXObject MSXML - DOMDocument, while Mozilla uses the built-in implementation to create a Document. Chrome on the other hand uses the built-in XmlHttpRequest object as the only available XML document object.)
Load the XSL document similarly and set its arguments.
Transform the XML and obtain output as a string.
Apply the string output to any page element.
Note that the code differs for each browser so it may be simpler to use a public JS framework such as JQuery or Prototype.
You will need to use html entities. For example this is how you would write a name tag
<name>.
More reading here