I've been fighting with this for some time now, and haven't been able to find a clear answer to this yet.
As I understand correctly I can store data in an XML file, validate it using an XSD and then display the data neatly using an XSLT.
However I've been having issues trying to perform XPath queries to select the data I wish to display in my XSLT. When I use generic selectors like './/' or '*' I get the results I'd expect. However when I try to use more specific selectors like : 'root/responses' or any other variant hereof, I get no results.
The XML file is validated correctly by the XSD, so I guess my data is at least somewhat correct. When I remove the XSD reference in the XML file, effectively removing the data validation, my XPath queries suddenly do work! Is there something I'm missing? I've tried adding namespace references to the XSLT but to no avail.
I've described the XSD, Sample XL and Sample XSLT below. Any help or hints would be appreciated!
The XSD, defining the structure, is as follows. This XSD describes a simple document, which nests three elements, and applies a restraint; the code of the responses'code must be unique.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="uitext"
targetNamespace="http://foo.bar/responsecode.xsd"
elementFormDefault="qualified"
xmlns:responsecodes="http://foo.bar/responsecode.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="responsecodes:rootType">
<xs:key name="responseCode">
<xs:selector xpath="responsecodes:responses/responsecodes:response">
<xs:annotation>
<xs:documentation>All defined responsecodes</xs:documentation>
</xs:annotation>
</xs:selector>
<xs:field xpath="@code">
<xs:annotation>
<xs:documentation>Unique responsecode</xs:documentation>
</xs:annotation>
</xs:field>
</xs:key>
</xs:element>
<xs:complexType name="rootType">
<xs:sequence>
<xs:element name="responses" minOccurs="1" maxOccurs="1" type="responsecodes:responseList">
<xs:annotation>
<xs:documentation>Defined responsecodes</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="responseList">
<xs:sequence>
<xs:element name="response" minOccurs="0" maxOccurs="unbounded" type="responsecodes:response"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="response">
<xs:sequence>
<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
Explains the use of the responsecode.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="code" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Unique code representing the response provided.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:schema>
An example XML document can be as follows:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="responsecode.xsl"?>
<root xmlns="http://foo.bar/responsecode.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://foo.bar/responsecode.xsd responsecode.xsd">
<responses>
<response code="firstCode">
<description>Explanation of first code</description>
</response>
<response code="secondCode">
<description>Explanation of second code</description>
</response>
<response code="thirdCode">
<description>Explanation of third code.</description>
</response>
</responses>
</root>
The test XSLT document referred to in the XML file is as follows. (This would display the codes as mentioned in a format that would resemble VS2008 enumeration definitions, but that aside)
<?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>Responses</h2>
<xsl:for-each select="root/responses/response">
<xsl:choose>
<xsl:when test="description != ''">
<br/>'''<description>
<br/>'''<xsl:value-of select="description" />
<br/>'''</description>
</xsl:when>
</xsl:choose>
<br/>
<xsl:value-of select="@code" />
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>