elementFormDefault 在 XSD 中做了啥?

Posted

技术标签:

【中文标题】elementFormDefault 在 XSD 中做了啥?【英文标题】:What does elementFormDefault do in XSD?elementFormDefault 在 XSD 中做了什么? 【发布时间】:2010-11-30 14:13:32 【问题描述】:

elementFormDefault 有什么作用,应该在什么时候使用?

所以我找到了elementFormDefault 值的一些定义:

qualified - 元素和属性 位于目标名称空间中 架构

不合格 - 元素和 属性没有命名空间

因此,根据该定义,我认为如果将架构​​设置为合格,那么为什么必须在类型前面加上命名空间?在哪些情况下,您甚至会为此设置一组不合格的?我尝试了谷歌搜索,但我得到的只是几个非常难以理解的 W3C 页面。

这是我现在正在使用的文件,为什么当我将targetNamespace 声明为与xmlns:target 相同的类型时,我需要将类型声明为target:TypeAssignments

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns" 
        elementFormDefault="qualified">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignments" type="target:TypeAssignments"
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="TypeAssignments">
    <sequence>
      <element name="assignment" type="target:assignmentInfo"
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
  </complexType>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
      <element name="page" type="target:TypePage"/>
      <element name="file" type="target:TypeFile" 
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
  <simpleType name="TypePage">
    <restriction base="integer">
      <minInclusive value="50" />
      <maxInclusive value="498" />
    </restriction>
  </simpleType>
  <simpleType name="TypeFile">
    <restriction base="string">
      <enumeration value=".xml" />
      <enumeration value=".dtd" />
      <enumeration value=".xsd" />
    </restriction>
  </simpleType>
</schema>

【问题讨论】:

【参考方案1】:

ElementFormDefault 与 schema 中类型的命名空间无关,它与 XML 文档中符合 schema 的元素的命名空间有关。

这是规范的相关部分:

Element Declaration Schema

Component Property  target namespace
Representation      If form is present and its ·actual value· is qualified, 
                    or if form is absent and the ·actual value· of 
                    elementFormDefault on the <schema> ancestor is qualified, 
                    then the ·actual value· of the targetNamespace [attribute]
                    of the parent <schema> element information item, or 
                    ·absent· if there is none, otherwise ·absent·.

这意味着您在架构顶部声明的 targetNamespace 仅适用于架构兼容 XML 文档中的元素,前提是 elementFormDefault 为“合格”或元素在架构中显式声明为具有 form= “合格”。

例如:如果 elementFormDefault 不合格 -

<element name="name" type="string" form="qualified"></element>
<element name="page" type="target:TypePage"></element>

期望“name”元素位于 targetNamespace 中,而“page”元素位于 null 命名空间中。

为了让您不必在每个元素声明中添加 form="qualified",声明 elementFormDefault="qualified" 意味着 targetNamespace 适用于每个元素,除非通过在元素声明中添加 form="unqualified" 来覆盖。

【讨论】:

虽然这个答案是指规范,但它并没有正确解释它。本地定义的元素仍在 targetNamespace 中,并且从不在 null 命名空间中。 elementFormDefault 只是一个开关,它指定您是否应该在实例中对它们进行命名空间限定。 @Ihe,这是不正确的:或者无论如何,它很容易混淆人们。如果本地元素声明没有 form=qualified,则元素声明架构组件的 target namespace 属性为“absent”,这意味着元素实例的命名空间 URI 属性也必须为“absent”。 @MichaelKay 对我来说这更令人困惑。问题是示例页面中是否位于 null 命名空间中,因为如果是这样,规范为什么不简单地说设置 elementFormDefault = unqualified 会将本地定义的元素放在 null 命名空间中。是说页面在实例中不应该是命名空间限定的,就像说页面不在命名空间中一样,因为这是为什么规范不简单地这么说,以及为什么带有 targetNamespace 的模式验证不是的东西在那个命名空间中? 它并没有“简单地这么说”,因为您对它的描述非常非正式:“将元素放入 null 命名空间”这一短语没有使用 XSD 规范的术语;规范更喜欢使用更谨慎的术语,这通常会让人难以阅读,但最终会更加精确。 就我而言,这是一个正确的答案。【参考方案2】:

考虑author元素使用的以下ComplexType AuthorType

<xsd:complexType name="AuthorType">
  <!-- compositor goes here -->
  <xsd:sequence>
     <xsd:element name="name" type="xsd:string"/>
     <xsd:element name="phone" type="tns:Phone"/>
  </xsd:sequence>
  <xsd:attribute name="id" type="tns:AuthorId"/>
</xsd:complexType>
<xsd:element name="author" type="tns:AuthorType"/>

如果elementFormDefault="unqualified"

那么下面的 XML 实例是有效的

<x:author xmlns:x="http://example.org/publishing">
   <name>Aaron Skonnard</name>
   <phone>(801)390-4552</phone>
</x:author>

允许作者的姓名属性不指定命名空间(不合格)。属于 &lt;xsd:complexType&gt; 的任何元素都被视为 complexType 的本地元素。

如果elementFormDefault="qualified"

那么实例应该具有限定的本地元素

<x:author xmlns:x="http://example.org/publishing">
   <x:name>Aaron Skonnard</name>
   <x:phone>(801)390-4552</phone>
</x:author>

更多详情请参考this链接

【讨论】:

嗯...name 是一个元素,而不是一个属性。【参考方案3】:

对一个老的常见问题的新的、详细的答案和解释......

简答:如果不将elementFormDefault="qualified"添加到xsd:schema,那么默认的unqualified值意味着本地声明的元素在没有命名空间 .

关于elementFormDefault 的作用有很多困惑,但可以通过一个简短的示例快速澄清......

XSD 的简化版本:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignment" type="target:assignmentInfo" 
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
</schema>

要点:

assignment 元素是本地定义的。 在 XSD 中本地定义的元素默认不在命名空间中。 这是因为elementFormDefault 的默认值为unqualified。 这可以说是 XSD 创建者的设计错误。 标准做法是始终使用elementFormDefault="qualified" 这样assignment 就在目标命名空间中 期待。 这是xs:element 声明中很少使用的form 属性,elementFormDefault 为其建立默认值。

看似有效的 XML

根据上面的 XSD,这个 XML 看起来应该是有效的:

<assignments xmlns="http://www.levijackson.net/web340/ns"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.levijackson.net/web340/ns try.xsd">
  <assignment id="a1">
    <name>John</name>
  </assignment>
</assignments>

注意:

assignments 上的默认命名空间将 assignments 及其所有后代放在默认命名空间 (http://www.levijackson.net/web340/ns) 中。

令人费解的验证错误

尽管看起来有效,但上述 XML 会产生以下令人困惑的验证错误:

[错误] try.xml:4:23: cvc-complex-type.2.4.a: 无效内容是 发现从元素“赋值”开始。 “assignment”之一是 预计。

注意事项:

您不会是第一个诅咒此诊断的开发人员,该诊断似乎说 内容无效,因为它希望找到一个 assignment 元素,但它实际上找到了一个 assignment 元素。WTF) 这究竟意味着什么:assignment 周围的 意味着验证期待 assignment 在没有命名空间中。不幸的是,当它说它找到了一个 assignment 元素时,它没有提到它在一个不同于没有命名空间的默认命名空间中找到它。

解决方案

绝大多数时间:将elementFormDefault="qualified" 添加到XSD 的xsd:schema 元素中。这意味着当在 XSD 中本地声明时,有效的 XML 必须将元素放置在目标命名空间中;否则,有效的 XML 必须将本地声明的元素放置在任何命名空间中。 少数情况:更改 XML 以符合 XSD 的要求 要求assignment 不在命名空间中。这可以实现, 例如,通过将 xmlns="" 添加到 assignment 元素。

致谢:感谢Michael Kay对此答案提供有用的反馈。

【讨论】:

“[元素] 周围的 和 ”... 啊!这就是让我找到解决我一个小时以来一直在努力解决的问题的原因,现在!谢谢!【参考方案4】:

elementFormDefault 需要注意的重要一点是,它适用于 本地 定义的元素,通常是在 complexType 块中命名的元素,而不是在架构顶层定义的全局元素。使用 elementFormDefault="qualified",您可以在 xml 文档中使用架构的目标命名空间作为文档的默认命名空间来处理架构中的本地元素。

在实践中,使用 elementFormDefault="qualified" 能够在嵌套块中声明元素,否则您必须在顶层声明所有元素并使用 ref 属性在嵌套元素的架构中引用它们,导致架构不那么紧凑。

XML Schema Primer 中的这一点谈到它:http://www.w3.org/TR/xmlschema-0/#NS

【讨论】:

稍微澄清一下看起来最准确的答案。使用 elementFormDefault=qualified 您必须命名空间限定实例中的本地元素。将其设置为不合格时,您不得命名空间限定它们。【参考方案5】:

elementFormDefault="qualified" 用于控制 XML 实例文档(.xml 文件)中命名空间的使用,而不是模式文档本身(.xsd 文件)中的命名空间。

通过指定 elementFormDefault="qualified",我们强制在使用此模式验证的文档中使用命名空间声明。

通常的做法是指定这个值来声明元素应该是合格的而不是不合格的。但是,由于 attributeFormDefault="unqualified" 是默认值,因此如果不想限定命名空间,则不需要在架构文档中指定它。

【讨论】:

elementFormDefault 仅适用于本地定义的元素。无论如何,全局元素都必须经过命名空间限定。【参考方案6】:

我注意到如果使用 elementFormDefault="qualified",XMLSpy(至少 2011 版本)需要定义一个 targetNameSpace。否则无法验证。并且也不会生成带有命名空间前缀的 xmls

【讨论】:

以上是关于elementFormDefault 在 XSD 中做了啥?的主要内容,如果未能解决你的问题,请参考以下文章

XML / XSD中的唯一约束

递归定义元素中的XSD元素

将XSD架构内容添加到架构集时出错

可以根据XSD中的属性值限制元素的出现次数吗?

在 nil xml 元素上指定属性

XML Schema 1.1 无法识别“断言”或“断言”