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

XML Namespaces, Schema validation(XSD) and 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 模式和一些示例记录,然后将内容可视化为a HTML 最后使用XSLT。其中一项任务表明我需要使用 "urn:students" 作为结构的默认命名空间。但是,当我这样做时,我没有收到最终可视化中的数据。当我从 XML 文件中删除“xmlns="urn:students"”时,一切正常。我已经阅读了一些关于 XML 命名空间的资料和教程,但我越来越困惑了。它应该和普通的编程语言一样,但同时又有很大的不同。我没有找到关于以下内容的明确解释:

  1. 如何 link 一个 XML 到一个模式?我是否需要 link 将文件添加到架构中,反之亦然?在我阅读的每一本 article/tutorial 中,都有不同的方法来实现这一点,但没有解释原因。
  2. 在这种情况下,我应该在 XML 和架构中包含哪些命名空间。

我也无法理解 XML 文件中“xmlns="urn:students"”定义的确切问题是什么。具有相同名称空间的模式中的元素是否未正确定义?为什么XSL拉不出来数据?

听起来您的 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:

How to link a XML to a schema? Do I need to link the file to the schema or vice versa? On every article/tutorial I read, there was a different way to achieve that and it was not explained why.

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

您的选择包括:

在验证时命名模式

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

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

使用xsi:schemaLocation

如果您想指向 XML 文档中的模式,作为记录文档含义的一种方式或在调用验证程序时节省您自己的输入,XSD 规范定义一种方法:在 XML 文档中使用 xsi:schemaLocation 属性。属性值包含一系列 space 分隔的 URI 对:名称space 名称,然后是该名称space 的架构文档的 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 定义了一个通用的 schema-linkage 机制,类似于 xml-stylesheet 处理指令;如果您愿意,可以使用它来代替 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-模型处理指令,如果在验证器的调用中没有指定模式文档,则可以查阅指定的模式文档;我不知道有什么副手,但我最近没有看过这个问题。如果 link 的目的是记录 XML 实例的概念框架,那当然没关系:人类读者可以使用处理指令来找到您想要有效的模式反对。