XML命名空间,模式验证(XSD)和XSLT

时间:2015-03-07 20:48:12

标签: xml xslt xsd xml-namespaces

我有一个XML文件,结构如下:

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="studentsStylesheet.xsl"?>
<students xmlns="urn:students">
  <student>
    ...
  </student>
</students>

XSD架构:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="urn:students"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="students">
    ...        
  </xs:element>
</xs:schema>

用于可视化的XSL文件(studentsStylesheet.xsl):

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      ...
    </html>
  </xsl:template>
</xsl:stylesheet>

我目前正在学习XML的简短课程,并且有一项任务是在XML文件中构建给定的XSD架构和一些示例记录,然后使用XSLT最终将内容可视化为HTML。其中一项任务表明我需要使用“urn:students”作为结构的默认命名空间。但是,当我这样做时,我没有收到最终可视化中的数据。当我从XML文件中删除“xmlns =”urn:students“”时,一切正常。我已经阅读了关于XML命名空间的一些材料和教程,但我更加困惑。它应该与普通编程语言中的相同,但同时它是完全不同的。我没有找到关于以下事项的明确解释:

  1. 如何将XML链接到架构?我是否需要将文件链接到架构,反之亦然?在我阅读的每篇文章/教程中,都有不同的方法来实现这一点,但没有解释原因。
  2. 我应该在XML和Schema中包含哪些名称空间。
  3. 我也无法理解XML文件中“xmlns =”urn:students“”定义的确切问题。模式中是否正确定义了元素,它们具有相同的命名空间?为什么XSL无法提取数据?

2 个答案:

答案 0 :(得分:2)

听起来你的XML和XSD(可能)没问题,问题在于你的XSLT。

XPath 1.0不允许使用默认命名空间。任何没有前缀的XPath段都被视为引用“null namespace”。

为了引用XPath中的命名空间,需要为其分配一个前缀(在XSLT中):

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:st="urn:students">

然后在你的XPath中使用它:

<xsl:value-of="st:Students/st:Student" />

答案 1 :(得分:2)

回答你的问题1:

  

如何将XML链接到架构?我是否需要将文件链接到架构,反之亦然?在我阅读的每篇文章/教程中,都有不同的方法来实现这一点,但没有解释原因。

没有要求从文档指向其XSD架构,但是有一些环境和情况可以方便地执行。大多数模式旨在处理无限大量的文档,因此在通常的情况下,从模式指向文档是非常麻烦的。因此,也许没有从架构文档指向实例文档的标准方法。

您的选择包括:

在验证时命名架构

如果要针对特定​​模式验证XML文档,最可靠的方法是在调用验证程序时指定XML文档的URI和所需模式文档的URI。大多数XSD验证器都应该有一个允许您执行此操作的调用接口。 (如果你使用的验证器没有,我的建议是获得一个新的验证器。但你应该自己做出决定。)

这种方法不需要XML文档中的任何内容指向架构文档;它是验证从不受信任的来源收到的文档的唯一可靠方法(因为如果您不相信它们提供有效的文档,您可能也不相信它们指向正确或商定的模式文档)。

使用xsi:schemaLocation

如果要指向XML文档中的模式,作为记录文档含义或在调用验证器时保存自己键入的方式,XSD规范定义了一种方法:使用xsi:schemaLocation属性你的XML文档。属性值包含一系列以空格分隔的URI对:名称空间名称,然后是该名称空间的模式文档的URI。所以你的XML文档可能会这样开始:

<students 
  xmlns="urn:students"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsl:schemaLocation="urn:students
    http://yoursite.example.com/2015/students.xsd"
> ...

如果在调用验证程序时未指定任何架构文档,则许多XSD验证程序将默认读取xsi:schemaLocation属性中指定的架构文档。

使用xml-model处理指令

W3C定义了一个类似于xml-stylesheet处理指令的通用模式链接机制;如果您愿意,可以使用它来代替xsi:schemaLocation属性,或者除了xsi:schemaLocation属性之外还可以使用它。然后,XML的开头可能如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" 
  href="studentsStylesheet.xsl"?>
<?xml-model type="application/xml"
  schematypens="http://www.w3.org/2001/XMLSchema"
  href="http://www.w3.org/2001/XMLSchema" 
  title="My excellent XSD Schema"?>
<students xmlns="urn:students"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsl:schemaLocation="urn:students
    http://yoursite.example.com/2015/students.xsd"
>

type 伪属性通常可以省略(验证器在取消引用URI时会找出架构的MIME类型),而 schematypens 也可能是可以省略的(验证者会看到,当它获得架构时,它是什么样的架构); title 伪属性供可以使用它的软件使用。

如果在验证器的调用中没有指定模式文档,可能有XSD验证器可以读取和理解xml模型处理指令并查阅指定的模式文档;我不知道有什么副手,但我最近没有看过这个问题。如果链接的目的是记录XML实例的概念框架,当然,这并不重要:人类读者可以使用处理指令来找到您想要有效的模式。