XML 命名空间、架构验证 (XSD) 和 XSLT



我有一个具有以下结构的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 和架构中包含哪些命名空间。

我也无法理解XML文件中"xmlns="urn:students"定义的确切问题是什么。元素不是在具有相同命名空间的架构中正确定义吗?为什么 XSL 无法拉取数据?

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

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

为了在 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:

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

不需要从文档指向其 XSD 架构,但在某些环境和情况下这样做很方便。 大多数架构旨在处理无限大量的文档,因此在通常情况下,从架构指向文档会非常麻烦;出于这个原因,也许没有从架构文档指向实例文档的标准方法。

您的选项包括:

在验证时命名架构

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

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

使用 xsi:schemaLocation

如果要指向 XML 文档中的

架构,作为记录文档含义的一种方式,或者为了节省在调用验证程序时键入的内容,XSD 规范定义了一种方法:在 XML 文档中使用 xsi:schemaLocation 属性。 属性值包含一系列以空格分隔的 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 模型处理指令

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"
>

类型伪属性通常可以省略(验证器在取消引用 URI 时会找出模式的 MIME 类型),并且模式类型也可以被省略(验证器在获取模式时会看到它是哪种模式);标题伪属性可供可以使用它的软件使用。

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

最新更新