0

编辑:前言:

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

目标:

让 xml 验证;“any”元素应该只检查元素的目标命名空间。即,只有元素“stuff”或“Product”(以及它的子元素)应该验证。

错误:

“匹配的通配符是严格的,但找不到元素‘stuff’的声明。” 我要严格匹配!

模式 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

4

1 回答 1

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>元素只能作为 element 的<Company>元素有效。绝不能在其他任何地方找到!

但是,在您的 XML 中:

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

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

XML 验证器并没有说您的<stuff>元素不能在其中使用, <Product>因为它是<Company>. 对它来说,本地元素由路径决定:

Company/stuff

当它找到<stuff>within<Product>时,它会寻找一条路径:

Company/Product/stuff

这是它不知道的。然后,它只是说它找不到<stuff>. 它不会进一步分析您可能做错了什么。

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

于 2013-06-19T00:20:25.160 回答