【问题标题】:Allowing ANY elements from a particular namespace with two schemas允许来自具有两个模式的特定命名空间的任何元素
【发布时间】:2013-06-18 16:06:19
【问题描述】:

编辑:前言:

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

目标:

让 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

【问题讨论】:

    标签: xml xsd xml-validation xsd-validation


    【解决方案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>
    

    那么,有什么问题呢?

    问题是您已在 本地 声明它。 它的实际意思是,根据你的模式, 您的&lt;staff&gt; 元素只能作为&lt;Company&gt; 元素的子元素 有效。 它不能在其他任何地方找到!

    但是,在您的 XML 中:

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

    您确实想将&lt;stuff&gt; 也用作&lt;Product&gt; 的子级, 这不是您的架构提供的。

    XML 验证器没有说您的 &lt;stuff&gt; 元素不能在其中使用 &lt;Product&gt; 因为它是&lt;Company&gt; 的本地孩子。 对它来说,本地元素是由路径决定的:

    Company/stuff
    

    当它在&lt;Product&gt; 中找到&lt;stuff&gt; 时,它会寻找路径:

    Company/Product/stuff
    

    这是未知的。然后,它只是说找不到&lt;stuff&gt; 的声明。它不会进一步分析您可能做错了什么。

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

    【讨论】:

    • 架构重新设计有帮助,我实际上将元素声明从 company.org 移动到导入的架构 product.org。然后我在 company.org 中添加了一个“any”。我会尽快用解决方案更新我的帖子。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多