我已经和它斗争了一段时间了,但还没有找到一个明确的答案.
据我所知,我可以将数据存储在XML文件中,使用XSD验证它,然后使用XSLT巧妙地显示数据.
但是,我一直在尝试执行XPath查询以选择我希望在XSLT中显示的数据时遇到问题.当我使用像’.//’或’*’这样的通用选择器时,我会得到我期望的结果.但是当我尝试使用更具体的选择器时,例如:’root / responses’或其他任何变体,我都没有得到任何结果.
XSD正确验证了XML文件,所以我想我的数据至少有点正确.当我删除XML文件中的XSD引用时,有效地删除了数据验证,我的XPath查询突然发挥作用!有什么我想念的吗?我已经尝试添加命名空间引用到XSLT但无济于事.
我在下面描述了XSD,Sample XL和Sample XSLT.任何帮助或提示将不胜感激!
定义结构的XSD如下.这个XSD描述了一个简单的文档,它嵌套了三个元素,并应用了约束;响应代码必须是唯一的.
<?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>
示例XML文档可以如下:
<?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>
XML文件中引用的测试XSLT文档如下所示. (这将以类似VS2008枚举定义的格式显示代码,但旁边除外)
<?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>
简单问题:您的XML元素位于XSLT一无所知的命名空间中.
<root xmlns="http://foo.bar/responsecode.xsd"> <responses> <!-- ... --> </responses> </root>
把你的< root>和所有后代元素到“http://foo.bar/responsecode.xsd”命名空间.
像这样更改你的XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://foo.bar/responsecode.xsd" exclude-result-prefixes="foo" > <xsl:template match="/"> <html> <body> <h2>Responses</h2> <xsl:for-each select="foo:root/foo:responses/foo:response"> <!-- ... --> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>
请注意声明命名空间的方式并给出前缀.稍后,使用该前缀引用该命名空间中的所有节点. exclude-result-prefixes用于确保命名空间不会不必要地出现在输出中.