允许具有两个模式的特定名称空间中的任何元素

时间:2013-06-18 16:06:20

标签: xml xsd xml-validation xsd-validation

编辑:前言:

以下是标题中描述的问题的特定实例。我有一个由两个文件共享的命名空间;一个进口另一个。但是,导入似乎会混淆元素“any”上的namespace属性。

目标:

让xml验证; “any”元素应仅检查元素的目标名称空间。即,只有元素“stuff”或“Product”(及其子项)才能验证。

错误:

“匹配的通配符是严格的,但是找不到声明      元素'东西'。“ 我想要严格匹配!

架构1:

<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.company.org"
        xmlns="http://www.company.org"
        elementFormDefault="qualified">

<xsd:include schemaLocation="http://www.product.org"/>

<xsd:element name="Company">

    <xsd:complexType>
        <xsd:sequence>
            <xsd:element name="Product" type="ProductType"
                         maxOccurs="unbounded"/>

            <xsd:element name="stuff" type="xsd:string" />
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

架构2:

<xsd:schema 
    xmlns="http://www.company.org" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.company.org" 
    elementFormDefault="qualified"
>

<xsd:complexType name="ProductType">
    <xsd:sequence>
       <xsd:any minOccurs="1" maxOccurs="unbounded"
        namespace="targetNamespace" />
    </xsd:sequence>
</xsd:complexType>

XML:

<?xml version="1.0"?>
<Company xmlns="http://www.company.org"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.company.org /u/name/test/file1.xsd"
>

    <Product>
            <stuff>Widget</stuff>
    </Product>
    <stuff>text</stuff>
</Company>

编辑:思考:

根据错误,看起来好像xml找不到声明“stuff”的模式,这是targetNamespace,“http://www.company.org!我很遗憾为什么会这样。帮助将非常感激,因为这个问题已经让我困扰了2天。

编辑2:解决方案:

架构1(http://www.company.org):     

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.company.org"
        xmlns="http://www.company.org"
        elementFormDefault="qualified">

    <xsd:include schemaLocation="http://www.product.org"/>

    <xsd:element name="Company">
        <xsd:complexType>
            <xsd:choice minOccurs="0" maxOccurs="unbounded" >
                <xsd:any namespace="##targetNamespace"  />
            </xsd:choice>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

架构2(http://www.product.org):

<xsd:schema 
    xmlns="http://www.company.org" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.company.org" 
    elementFormDefault="qualified"
    >

    <xsd:simpleType name="stuff">
        <xsd:restriction base="xsd:string" />
    </xsd:simpleType>

    <xsd:complexType name="ProductType">
        <xsd:sequence>
            <xsd:any minOccurs="1" maxOccurs="unbounded" 
            namespace="http://www.company.org" processContents="strict" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element name="Product" type="ProductType" />
    <xsd:element name="stuff" type="stuff" />

</xsd:schema>

到目前为止,这个解决方案对我来说非常有效。元素“any namespace =”## targetNamespace“/”将查找包含在中心的每个元素,包括文件。美妙的是,通过这个设置,命名空间是同构的,所以我可以忽略xml和xsd文件中的前缀,同时包括任意数量的支持模式,但我只需要一个文件来验证。

欢迎回复:D

1 个答案:

答案 0 :(得分:1)

看,你有这个错误:

匹配的通配符是严格的,但是找不到元素'stuff'的声明。

注意,它没有说明元素的名称空间。 相反,它只是找不到元素stuff的声明!

然而,从表面上看,你似乎确实声明了那个元素:

<xsd:element name="Company">
  <xsd:complexType>
    <xsd:sequence>
       <xsd:element name="Product" type="ProductType"
                    maxOccurs="unbounded"/>

       <xsd:element name="stuff" type="xsd:string" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

那么,问题是什么?

问题是您已将其声明为本地。 实际意味着,根据你的模式, 您的<staff>元素只能作为<Company>元素的子元素有效。 在其他任何地方都找不到它!

但是,在您的XML中:

<Product>
        <stuff>Widget</stuff>
</Product>
<stuff>text</stuff>

您确实希望将<stuff>也用作<Product>的孩子, 这不是您的架构提供的。

XML验证程序未说明您的<stuff>元素无法在其中使用 <Product>因为它是<Company>的当地孩子。 对它来说,本地元素由路径确定:

Company/stuff

当它在<stuff>内找到<Product>时,它会查找路径:

Company/Product/stuff

这是未知的。然后,它只是说它找不到<stuff>的声明。它没有进一步分析你可能做错了什么。

因此,问题实际上不是关于命名空间,而是关于本地声明的元素。 你应该重新设计你的模式来修复它!