XML 架构:根元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8854144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 15:06:29  来源:igfitidea点击:

XML Schema: root element

xmlxsd

提问by johngoche9999

The following post asks how to indicate that an element is the root element in an XML schema:

以下帖子询问如何指示一个元素是 XML 模式中的根元素:

Is it possible to define a root element in an XML Document using Schema?

是否可以使用 Schema 在 XML 文档中定义根元素?

I have followed the w3schools tutorial on XML Schema but something is still not clear. Consider example schema 2 from http://www.w3schools.com/schema/schema_example.asp(reproduced below for convenience). How does this code indicate that <shiporder>is the root element? Isn't the example saying that all elements are valid as root elements?

我已经关注了 w3schools 教程关于 XML 架构,但仍有一些不清楚。考虑来自http://www.w3schools.com/schema/schema_example.asp 的示例模式 2 (为方便起见,复制如下)。这段代码如何表明它<shiporder>是根元素?这个例子不是说所有元素都作为根元素有效吗?

------------------ instance ----------------------------------

- - - - - - - - - 实例 - - - - - - - - - - - - - - - - ---

<?xml version="1.0" encoding="ISO-8859-1"?>

<shiporder orderid="889923"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="shiporder.xsd">
  <orderperson>John Smith</orderperson>
  <shipto>
    <name>Ola Nordmann</name>
    <address>Langgt 23</address>
    <city>4000 Stavanger</city>
    <country>Norway</country>
  </shipto>
  <item>
    <title>Empire Burlesque</title>
    <note>Special Edition</note>
    <quantity>1</quantity>
    <price>10.90</price>
  </item>
  <item>
    <title>Hide your heart</title>
    <quantity>1</xample saying that all elements are valid as root elements?quantity>
    <price>9.90</price>
  </item>
</shiporder> 

----------------------- schema ------------------------

----------------------- 架构 ------------------------

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>

<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>

<!-- definition of complex elements -->
<xs:element name="shipto">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="name"/>
      <xs:element ref="address"/>
      <xs:element ref="city"/>
      <xs:element ref="country"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="item">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="title"/>
      <xs:element ref="note" minOccurs="0"/>
      <xs:element ref="quantity"/>
      <xs:element ref="price"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="shiporder">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="orderperson"/>
      <xs:element ref="shipto"/>
      <xs:element ref="item" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute ref="orderid" use="required"/>
  </xs:complexType>
</xs:element>

</xs:schema>


From my point of view an XML Schema should do two things:

从我的角度来看,XML Schema 应该做两件事:

  1. define what can occur inside each node
  2. define where each node can be placed
  1. 定义每个节点内可能发生的事情
  2. 定义每个节点可以放置的位置

And it seems the example fails at #2. Any Suggestions?

似乎这个例子在#2 处失败了。有什么建议?

采纳答案by Has QUIT--Anony-Mousse

As far as I know, any globallydefined element can be used as root element, and XML Schema does not have a notion for specifying what the root element is supposed to be.

据我所知,任何全局定义的元素都可以用作根元素,而 XML Schema 没有指定根元素应该是什么的概念。

You can however work around this by designing your XML Schema well, so that there is only one globally defined element - then only this element is valid as root element.

但是,您可以通过很好地设计 XML 模式来解决这个问题,这样只有一个全局定义的元素 - 只有这个元素作为根元素有效。

An example of this can be found at W3Schools(heading Using Named Types) This example only has one globally defined element, and thus only one possible root element.

W3Schools 中可以找到这样的一个例子(标题Using Named Types)这个例子只有一个全局定义的元素,因此只有一个可能的根元素。

回答by Michael Kay

Not everyone agrees with it, but the fact that XML Schema can't specify a root element is by design. The thinking is that if an <invoice>is valid when it's the only thing in a document, then it is equally valid if it is contained in something else. The idea is that content should be reusable, and you shouldn't be allowed to prevent someone using valid content as part of something larger.

并非所有人都同意这一点,但 XML Schema 无法指定根元素的事实是设计使然。这种想法是,如果 an<invoice>在它是文档中唯一的内容时有效,那么如果它包含在其他内容中,则它同样有效。这个想法是内容应该是可重用的,你不应该被允许阻止某人使用有效内容作为更大的东西的一部分。

(The fact that ID and IDREF are scoped to a document rather goes against this policy; but then the language was designed by a rather large committee.)

(事实上​​,ID 和 IDREF 被限定在一个文档中,而不是违反了这个政策;但是这种语言是由一个相当大的委员会设计的。)

回答by davogotland

yes, you are right. the xsd should be:

你是对的。xsd 应该是:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>

<!-- definition of complex elements -->
<xs:complexType name="shiptoType">
  <xs:sequence>
    <xs:element name="name" type="xs:string" />
    <xs:element name="address" type="xs:string" />
    <xs:element name="city" type="xs:string" />
    <xs:element name="country" type="xs:string" />
  </xs:sequence>
</xs:complexType>

<xs:complexType name="itemType">
  <xs:sequence>
    <xs:element name="title" type="xs:string" />
    <xs:element name="note" minOccurs="0" type="xs:string" />
    <xs:element name="quantity" type="xs:string" />
    <xs:element name="price" type="xs:string" />
  </xs:sequence>
</xs:complexType>

<xs:element name="shiporder">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="orderperson" type="xs:string" />
      <xs:element name="shipto" type="shiptoType"/>
      <xs:element name="item" maxOccurs="unbounded" type="itemType"/>
    </xs:sequence>
    <xs:attribute ref="orderid" use="required"/>
  </xs:complexType>
</xs:element>

</xs:schema>

as you see, now there is only one xs:element, and that one is the only one that can be a valid root element :)

如您所见,现在只有一个xs:element,并且是唯一一个可以作为有效根元素的 :)

回答by xmlDave

The disadvantage of lots of global elements is they could all be used as root elements for documents. The advantage is then you can use the element when defining new types which will assure the namespace of the child elements match those of the parent type.

许多全局元素的缺点是它们都可以用作文档的根元素。优点是您可以在定义新类型时使用该元素,这将确保子元素的命名空间与父类型的命名空间相匹配。

I have changed from thinking there should only be one global element to that all complex types should have a global element.

我已经从认为应该只有一个全局元素转变为所有复杂类型都应该有一个全局元素。

回答by Johnny Qian

Based on the example that you provided, it is possible to find the only root element.

根据您提供的示例,可以找到唯一的根元素。

You can get a list of global elements, then get a list a nested elements that referenced in complexType under the node xs:sequence, thus the root element is the one in global elements list but not in nested elements list.

您可以获取全局元素列表,然后获取节点xs:sequence 下的complexType 中引用的嵌套元素列表,因此根元素是全局元素列表中的元素,而不是嵌套元素列表中的元素。

I have done this by using XmlSchemaSet class in .NET. Here is the code snippet:

我通过在 .NET 中使用 XmlSchemaSet 类来做到这一点。这是代码片段:

var localSchema = schemaSet.Schemas().OfType<XmlSchema>().Where(x => !x.SourceUri.StartsWith("http")).ToList();

var globalComplexTypes = localSchema
.SelectMany(x => x.Elements.Values.OfType<XmlSchemaElement>())
.Where(x => x.ElementSchemaType is XmlSchemaComplexType)
.ToList();

var nestedTypes = globalComplexTypes.Select(x => x.ElementSchemaType)
.OfType<XmlSchemaComplexType>()
.Select(x => x.ContentTypeParticle)
.OfType<XmlSchemaGroupBase>()
.SelectMany(x => x.GetNestedTypes())
.ToList();

var rootElement= globalComplexTypes.Single(x => !nestedTypes.Select(y => y.ElementSchemaType.QualifiedName).Contains(x.SchemaTypeName));

The extension method GetNestedTypes:

扩展方法 GetNestedTypes:

static IEnumerable<XmlSchemaElement> GetNestedTypes(this XmlSchemaGroupBase xmlSchemaGroupBase)
{
    if (xmlSchemaGroupBase != null)
    {
        foreach (var xmlSchemaObject in xmlSchemaGroupBase.Items)
        {
            var element = xmlSchemaObject as XmlSchemaElement;
            if (element != null)
                yield return element;
            else
            {
                var group = xmlSchemaObject as XmlSchemaGroupBase;
                if (group != null)
                    foreach (var item in group.GetNestedTypes())
                        yield return item;
            }
        }
    }
}

But there still has problems for the general xsd when using this approach. For example, in DotNetConfig.xsd that Visual studio use for configuration file, the root element is define as below:

但是在使用这种方法时,一般的 xsd 仍然存在问题。例如,在 Visual Studio 用于配置文件的 DotNetConfig.xsd 中,根元素定义如下:

  <xs:element name="configuration">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any namespace="##any" processContents="lax" />
      </xs:choice>
      <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/>
    </xs:complexType>
  </xs:element>

I havn't found a complete solution to deal with all kinds of schemas yet. Will continue for it.

我还没有找到一个完整的解决方案来处理各种模式。将继续为它。

回答by Sunil

How does this code indicate that is the root element?

这段代码如何表明它是根元素?

John, That schema just defined all the elements and any of those can be chosen as a root element. If you try generating a sample xml from any tool like Altova XML Spy or its kind, you will get to choose an element to be the root element.

约翰,那个模式刚刚定义了所有元素,其中任何一个都可以被选为根元素。如果您尝试从 Altova XML Spy 或类似工具等任何工具生成示例 xml,您将可以选择一个元素作为根元素。

So any of those elements can be the root.

所以这些元素中的任何一个都可以是根。

To prevent ambiguity, use one globally defined element.

为防止歧义,请使用一个全局定义的元素。