Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xsl transform problem when referencing xsd in xml

Tags:

xml

xslt

xsd

I am fairly new to XSL and need help with a transformation issue. I have an XML file that is described by an XSD. I use an XSL file to transform the XML into HTML. I want to reference the XSD in the XML file, but when I do the XML doesn't get transformed.

Example XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="example.xsl"?>

<root>
<!--
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://localhost" xsi:schemaLocation="http://localhost example.xsd">
-->
  <element>Element 1</element>
  <element>Element 2</element>
  <element>Element 3</element>
</root>

Example XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <ul>
      <xsl:for-each select="root/element">
        <li><xsl:value-of select="."/></li>
      </xsl:for-each>
    </ul>
  </xsl:template>
</xsl:stylesheet>

Example XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://localhost"
  xmlns="http://localhost"
  elementFormDefault="qualified">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="element" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

In the XML, if I use the commented out root tag, Firefox and Chrome do not transform the xml. If I just use the plain <root> tag, however, the transformation happens fine.

Can anyone explain why the XSL transformation doesn't happen if I reference the XSD in my XML? Any help is appreciated!

like image 581
Jpnh Avatar asked Jan 06 '11 03:01

Jpnh


People also ask

How do I reference an XSD file in XML?

Reference the XSD schema in the XML document using XML schema instance attributes such as either xsi:schemaLocation or xsi:noNamespaceSchemaLocation. Add the XSD schema file to a schema cache and then connect that cache to the DOM document or SAX reader, prior to loading or parsing the XML document.

How does XSD work with XML?

XML defines the syntax of elements and attributes for structuring data in a well-formed document. XSD (akaXMLSchema), like DTD before, powers the eXtensibility in XML by enabling the user to define the vocabulary and grammar of the elements and attributes in a valid XML document.

How does XSLT transform XML?

XSLT is commonly used to convert XML to HTML, but can also be used to transform XML documents that comply with one XML schema into documents that comply with another schema. XSLT can also be used to convert XML data into unrelated formats, like comma-delimited text or formatting languages such as troff.


1 Answers

<!-- <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://localhost" xsi:schemaLocation="http://localhost example.xsd"> -->

This has nothing to do with using an XML Schema. The problem is that you specify a default namespace.

Using XPath expressions for node names in a default namespace is the biggest XPath FAQ.

Please, search the xpath and xslt tags for "default namespace" and you'll find many good answers.

The solution for XSLT is to declare a namespace with some prefix (say "x") and namespace-uri that is the same as the namespace-uri of the default namespace in the XML document. Then in any XPath expression use x:name instead of name.

Thus your XSLT code becomes:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="http://localhost" exclude-result-prefixes="x" >

    <xsl:template match="/">
        <ul>
            <xsl:for-each select="x:root/x:element">
                <li>
                    <xsl:value-of select="."/>
                </li>
            </xsl:for-each>
        </ul>
    </xsl:template>
</xsl:stylesheet>

and when applied on the provided XML document with uncommented <root> element:

<root xmlns="http://localhost"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://localhost example.xsd"> 
    <element>Element 1</element>
    <element>Element 2</element>
    <element>Element 3</element>
</root>

the wanted, correct result is produced:

<ul>
    <li>Element 1</li>
    <li>Element 2</li>
    <li>Element 3</li>
</ul>
like image 168
Dimitre Novatchev Avatar answered Nov 14 '22 01:11

Dimitre Novatchev