我只关心XML文件中是否存在某些特定的标记,而不关心其他标记。我应该如何编写xml模式文件?

我只关心XML文件中是否存在某些特定的标记,而不关心其他标记。我应该如何编写xml模式文件?,xml,xsd,Xml,Xsd,例如,我只关心父标记“person”中是否存在一些必要的子标记,例如“name”、“sex”。这些“必要”标签的出现顺序不是固定的(但这些标签的名称是固定的) 这没关系 <person> <name>peter</name> <sex>male</sex> </person> 彼得 男性的 这也可以。虽然职位改变了 <person> <sex>male</sex&g

例如,我只关心父标记“person”中是否存在一些必要的子标记,例如“name”、“sex”。这些“必要”标签的出现顺序不是固定的(但这些标签的名称是固定的)

这没关系

<person>
    <name>peter</name>
    <sex>male</sex>
</person>

彼得
男性的
这也可以。虽然职位改变了

<person>
    <sex>male</sex>
    <name>peter</name>
</person>

男性的
彼得
这也是可以的。(年龄,地址是不必要的,并且允许在人内的任何地方)


彼得
23
abc
男性的
这是不好的,因为一个必要的标记“name”不存在

<person>
    <age>23</age>
    <sex>male</sex>
</person>

23
男性的
您能告诉我如何编写xml模式来检查这一点吗?
。。。似乎不适合这种情况

补充:
事实上,除了标签“姓名”、“性别”之外,在父标签“个人”中还有许多(低于20个)其他“必要”标签。

可能需要类似以下内容:

<xs:element name="name" type="xs:string" minOccurs="1" />

在复杂类型规范中。比如说:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="person">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name" type="xs:string" minOccurs="1" />
              <xs:any minOccurs ="0" maxOccurs ="unbounded" processContents="lax"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>


前两个示例通过,但第三个示例失败。

使用序列,然后使用xsd:any

<xsd:element name="person">
    <xsd:complexType>
        <xsd:sequence>
        <xsd:element name="name" type="xsd:string" />
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>


不幸的是,您必须从“name”元素开始。

如果必须首先使用name元素,则很容易实现此内容模型:您定义一个由匹配名称的元素粒子组成的序列,然后是匹配任何内容的(可选、可重复)通配符粒子(xs:any)

如果name元素可以出现在任何地方,那么实现它就比较困难;问题是,在XSD 1.0中,内容模型最终变得模棱两可,因为当遇到name元素时,它既匹配name的特定元素粒子,也匹配通配符。XSD1.1巧妙地解决了这一问题,允许这种模糊性:元素将优先匹配通配符中的特定粒子。因此,在XSD1.1中,您可以编写

<xs:sequence>
  <xs:any minOccurs="0" maxOccurs="unbounded"/>
  <xs:element name="name"/>
  <xs:any minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>


可能还有另一种方法可以工作:使内容模型完全打开,但定义一个唯一性约束,即“名称”必须是唯一的。这意味着该名称必须存在。

亲爱的伯特·埃文斯,感谢您的回复。“其他标签”并不局限于“年龄”,事实上,我甚至不知道标签的名称,所以不可能列出所有的“其他标签”@user1067607,然后你会想使用xs:any。我在代码示例中添加了它。亲爱的Michael Kay,感谢您的回复。你的解决方案解决了我一半的问题。事实上,除了“name”标记外,我还有许多(低于20个)其他“必需”标记,并且这个“必需”标记的出现顺序无法限制,这意味着我必须使用“xs:all”而不是“xs:sequence”,但似乎“xs:any”不能在“xs:all”中使用。你能给我一些建议吗。你能给出一个“完全开放的内容模型加上独特的约束”的例子吗?再次感谢。您必须确保您的XML处理器能够支持XML模式1.1,但并非所有应用服务器都支持该级别。亲爱的阿基米德·特拉亚诺感谢您的回复。实际的问题稍微复杂一些,因为“name”元素并不总是第一个元素,而且除了“name”之外还有其他必需的元素。我可以想到的另一种方法是xsd:unique元素,但它也会提供约束。这将允许您通过XPath对元素进行检查,但它会检查唯一性。我可以想到的另一种方法是创建一个元素组,该组将列出您的排列。然而,我现在还不能想象这会是什么样子。然而,如果你需要这么宽松,你真的应该在应用程序代码中这样做。这里要容易得多,您仍然可以使用上面给出的技术(除去name元素)允许person下的任何内容。将特定于应用程序的逻辑移动到应用程序中并没有错,在JEE中,没有一种工具可以解决所有问题(任何人都可以轻松反驳)。
<xs:sequence>
  <xs:any minOccurs="0" maxOccurs="unbounded"/>
  <xs:element name="name"/>
  <xs:any minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>