XML验证混淆

时间:2010-03-03 21:18:32

标签: xml validation xsd

我承认,我是一个XML新手。我在针对模式验证某些xml时遇到问题。这是我的架构的相关部分:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.me.com/orpm/kpi/automation/report"
    targetNamespace="http://www.me.com/orpm/kpi/automation/report">
    <xs:attribute name="Pattern">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:enumeration value="Exact"/>
                <xs:enumeration value="Replace"/>
                <xs:enumeration value="Regex"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:attribute>
    <xs:complexType name="NameValue">
        <xs:all>
            <xs:element name="Value" type="xs:string"/>
        </xs:all>
        <xs:attribute ref="Pattern"/>
    </xs:complexType>
    <xs:element name="KpiReport">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Name" type="NameValue"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

这是失败的xml:

<?xml version="1.0"?>
<KpiReport xmlns="http://www.me.com/orpm/kpi/automation/report"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.me.com/orpm/kpi/automation/report filename.xsd">
    <Name Pattern="Exact">
        <Value>Test</Value>
    </Name>
</KpiReport>

失败并出现此错误:

Description: cvc-complex-type.2.4.a: Invalid content was found starting with element 'Name'. One of '{Name}' is expected.

我迷失了。请帮忙。

3 个答案:

答案 0 :(得分:2)

david是正确的,但更好的解决方法是通常将本地定义的元素定义为模式中的限定元素。 XSD在那里有一个可怕的默认值(这就是你的XSD没有按预期工作的原因),因此几乎所有工具都会生成一个空模式:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
</xs:schema>

这基本上与david建议的修复相同,但它是通过更改XSD默认值来实现的,这更加健壮。

对于究竟发生了什么的解释可能需要花费太长时间才能包含在这里,并且可能没那么大的兴趣。

答案 1 :(得分:2)

好吧,既然大卫要求它,这里有完整的解释:XSD中的元素声明可以是全局的也可以是本地的。全局声明直接位于xs:schema下的级别,本地声明是其他声明中的声明。根据定义,全局声明的元素始终在模式的targetNamespace中定义(如果有的话)。另一方面,本地声明默认情况下不在命名空间中(具体而言,不在模式的targetNamespace中),除非您通过已讨论的两种方法之一使它们“合格”。声明没有命名空间的元素的效果是文档必须看起来像这样(使用“Name”和“Value”元素作为没有名称空间限定名称的元素):

<?xml version="1.0"?> 
<KpiReport xmlns="http://www.me.com/orpm/kpi/automation/report"> 
    <Name xmlns=""> 
        <Value>Test</Value> 
    </Name> 
</KpiReport>

这不是很漂亮,绝对难以使用和理解,所以这种混合合格和不合格元素的风格从未使用过(我绝对没见过)。

答案 2 :(得分:1)

有几件事情正在发生,还有几个可能解决您问题的方法。

您可以使用的解决方案取决于您是否可以更改XML,XSD或两者。

下面是一些传递架构验证的XML:

<?xml version="1.0"?> 
<ns0:KpiReport xmlns:ns0="http://www.me.com/orpm/kpi/automation/report" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.me.com/orpm/kpi/automation/report filename.xsd"> 
    <Name ns0:Pattern="Exact"> 
        <Value>Test</Value> 
    </Name> 
</ns0:KpiReport>

关键区别在于你的xsd中没有在http://www.me.com/orpm/kpi/automation/report命名空间中定义Name元素。我不完全确定发生了什么但是认为在模式级别使用Pattern属性会让事情变得混乱。通过确定名称空间前缀ns0:告诉验证器KpiReport和Pattern都在该名称空间中,但Name不是。

此解决方案可能不适合,因此另一个选项是调整您的架构以接受您的示例XML。以下是一个有效的架构:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://www.me.com/orpm/kpi/automation/report" targetNamespace="http://www.me.com/orpm/kpi/automation/report" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="NameValue">
    <xs:all>
      <xs:element form="qualified" name="Value" type="xs:string" />
    </xs:all>
    <xs:attribute name="Pattern">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Exact" />
          <xs:enumeration value="Replace" />
          <xs:enumeration value="Regex" />
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>
  <xs:element name="KpiReport">
    <xs:complexType>
      <xs:sequence>
        <xs:element form="qualified" name="Name" type="NameValue" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

需要注意的是,Pattern属性现在移动到NameValue complexType中,并且Name和Value现在指定为form =“qualified”。限定意味着这些元素需要名称空间前缀(在这种情况下,前缀是默认值,或者没有)。

我不是百分之百确定为什么这是必需的 - 我的XSD知识足以达到这一点,但不知道发生了什么。我通常使用工具来生成我的模式,然后调整直到我做对了。

希望这对您有所帮助,或者XSD印章更清晰的人可以填补空白。