XSD使用名称空间属性验证XML

XSD使用名称空间属性验证XML,xml,validation,xsd,Xml,Validation,Xsd,我需要创建一个XSD来验证以下XML: <?xml version="1.0" encoding="UTF-8"?> <thing:cardAuthRequestResponse xmlns:thing="http://www.thing.com/thing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <thing:request xsi:type="thing:GiftC

我需要创建一个XSD来验证以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<thing:cardAuthRequestResponse 
    xmlns:thing="http://www.thing.com/thing" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <thing:request xsi:type="thing:GiftCardBalanceRequest" />
</thing:cardAuthRequestResponse>
XSD



我是否可以更改XSD以使用namespaced type属性验证XML,或者XML是否存在根本无效的内容?

您的XML似乎正在尝试创建一个动态XSD类型列表,其中包含内容并可以验证。使用xml并没有错,但如果自动生成的模式能够理解这一目标,我会感到惊讶

我修改了一些名称空间,使它们能够真正链接起来,并一起创建一个示例,说明这可能是什么样子

XSD-简单地定义您拥有一个
cardAuthRequestResponse
,其中包含任意数量的
request
元素。它们可以是
xs:anyType

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.enactor.com/retail">
    <xs:element name="cardAuthRequestResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="request" type="xs:anyType" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="GiftCardBalanceRequest">
    </xs:complexType>

    <xs:complexType name="AgeRequest">
        <xs:sequence>
            <xs:element name="age">
                <xs:simpleType>
                    <xs:restriction base="xs:nonNegativeInteger" />
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
现在,由于每个
都需要为它们定义
numRequests
属性。如果您有一个他们都必须填写的基本请求,这可能很有用。例如:

<?xml version="1.0" encoding="UTF-8"?>
<retail:cardAuthRequestResponse
        xmlns:retail="http://www.enactor.com/retail"
        xmlns:thing="http://www.thing.com/thing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <retail:request xsi:type="thing:GiftCardBalanceRequest" numRequests="2" />
    <retail:request xsi:type="thing:AgeRequest" numRequests="2">
        <thing:age>2</thing:age>
    </retail:request>
</retail:cardAuthRequestResponse>
<xsd:schema targetNamespace="http://www.thing.com/thing"
            xmlns:thing="http://www.thing.com/thing"
            xmlns:xsd="..."
            ... >
  <xsd:element name="cardAuthRequestResponse"/>
  <xsd:element name="request"/>
  <xsd:type name="GiftCardBalanceRequest"/>
</

2.

您的xml似乎正在尝试创建一个动态xsd类型列表,其中包含内容并可以进行验证。使用xml并没有错,但如果自动生成的模式能够理解这一目标,我会感到惊讶

我修改了一些名称空间,使它们能够真正链接起来,并一起创建一个示例,说明这可能是什么样子

XSD-简单地定义您拥有一个
cardAuthRequestResponse
,其中包含任意数量的
request
元素。它们可以是
xs:anyType

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.enactor.com/retail">
    <xs:element name="cardAuthRequestResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="request" type="xs:anyType" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="GiftCardBalanceRequest">
    </xs:complexType>

    <xs:complexType name="AgeRequest">
        <xs:sequence>
            <xs:element name="age">
                <xs:simpleType>
                    <xs:restriction base="xs:nonNegativeInteger" />
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
现在,由于每个
都需要为它们定义
numRequests
属性。如果您有一个他们都必须填写的基本请求,这可能很有用。例如:

<?xml version="1.0" encoding="UTF-8"?>
<retail:cardAuthRequestResponse
        xmlns:retail="http://www.enactor.com/retail"
        xmlns:thing="http://www.thing.com/thing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <retail:request xsi:type="thing:GiftCardBalanceRequest" numRequests="2" />
    <retail:request xsi:type="thing:AgeRequest" numRequests="2">
        <thing:age>2</thing:age>
    </retail:request>
</retail:cardAuthRequestResponse>
<xsd:schema targetNamespace="http://www.thing.com/thing"
            xmlns:thing="http://www.thing.com/thing"
            xmlns:xsd="..."
            ... >
  <xsd:element name="cardAuthRequestResponse"/>
  <xsd:element name="request"/>
  <xsd:type name="GiftCardBalanceRequest"/>
</

2.

首先,您的XSD不是有效的架构,因为xs:attribute的name属性必须是NCName(因此
xsi:type
无效)

通常,如果希望允许某个属性位于与架构的targetNamespace不同的命名空间中,则可以在具有自己的targetNamespace的不同架构文档中声明该属性,导入该架构文档,并使用“ref”而不是“name”引用该属性

但是
xsi:type
是特殊的:它被隐式声明并在任何元素上被隐式允许。因此,您可以简单地从模式中删除对
xsi:type
的引用

下一个问题是实例文档位于名称空间
http://www.thing.com/thing
,而您的模式定义命名空间
http://www.enactor.com/retail
。我不确定这是发布问题时发生的简单复制/粘贴错误,还是根本无法理解名称空间在确保模式有效性方面的重要性

如果我解决了这个问题,我只剩下一个错误:

test.xml第6行第62列的验证错误: FORG0001:在xsi:type属性中指定了未知类型{thing:giftCardBalancerRequest}

这是因为
xsi:type
的语义要求其值为模式中声明的类型的名称,而您的模式不包含此类类型


哦,尝试将xsi:type的声明写入任何文档的模式中是没有意义的;模式验证器使用它为元素选择类型(特别是覆盖默认类型分配),但它不会根据元素的声明进行验证。为xsi名称空间编写模式文档不是错误,但任何符合要求的处理器都不会使用它。

首先,您的XSD不是有效的模式,因为xs:attribute的name属性必须是NCName(因此
xsi:type
无效)

通常,如果希望允许某个属性位于与架构的targetNamespace不同的命名空间中,则可以在具有自己的targetNamespace的不同架构文档中声明该属性,导入该架构文档,并使用“ref”而不是“name”引用该属性

但是
xsi:type
是特殊的:它被隐式声明并在任何元素上被隐式允许。因此,您可以简单地从模式中删除对
xsi:type
的引用

下一个问题是实例文档位于名称空间
http://www.thing.com/thing
,而您的模式定义命名空间
http://www.enactor.com/retail
。我不确定这是发布问题时发生的简单复制/粘贴错误,还是根本无法理解名称空间在确保模式有效性方面的重要性

如果我解决了这个问题,我只剩下一个错误:

test.xml第6行第62列的验证错误: FORG0001:在xsi:type属性中指定了未知类型{thing:giftCardBalancerRequest}

这是因为
xsi:type
的语义要求其值为模式中声明的类型的名称,而您的模式不包含此类类型

哦,尝试将xsi:type的声明写入任何文档的模式中是没有意义的;模式验证器使用它为元素选择类型(特别是覆盖默认类型分配),但它不会根据元素的声明进行验证。为xsi名称空间编写模式文档不是一个错误,但任何符合要求的处理器都不会使用它

。。。XML是否存在根本无效的地方

没有一个XML实例不可能构建一个有效的模式。存在并且不可能存在“根本无效”的XML文档

在本例中,您可能需要花一两个小时阅读xsi:type attrib的使用
<xsd:schema targetNamespace="http://www.thing.com/thing"
            xmlns:thing="http://www.thing.com/thing"
            xmlns:xsd="..."
            ... >
  <xsd:element name="cardAuthRequestResponse"/>
  <xsd:element name="request"/>
  <xsd:type name="GiftCardBalanceRequest"/>
</