Allowing ANY elements from a particular namespace with two schemas

走远了吗. 提交于 2019-12-08 10:44:02

问题


EDIT:Preface:

Below is a particular instance of the problem described in the title. I have a single namespace shared by two documents; one imports the other. However, the import seems to confuse the namespace attribute on element"any".

The Goal:

To have the xml validate; "any" element should check only the target namespace for elements. I.e., Only element "stuff" or "Product" (and it's children) should validate.

The Error:

"The matching wildcard is strict, but no declaration can be found for element 'stuff'." I want strict matching!

Schema 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>

Schema 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>

EDIT: Thoughts:

Based on the error, it looks as if the xml can't find the schema that declares "stuff", which is the targetNamespace, "http://www.company.org! I'm lost as to why this is the case. Help would be GREATLY appreciated, as this problem has been bugging me for 2 days now.

EDIT 2: Solution:

Schema 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>

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>

This solution has worked beautifully for me so far. Element "any namespace="##targetNamespace" /" will find each element included in the central, including file. The beauty is in that with this set up, the namespace is homogeneous, so I can ignore prefixes in both the xml and xsd files, while including any number of supporting schema, but I only need one file to validate against.

Feedback welcome :D


回答1:


Look, you've got this error:

The matching wildcard is strict, but no declaration can be found for element 'stuff'.

Notice, it says nothing about namespaces of elements. Rather, it just cannot find a declaration for the element stuff!

Yet, on the surface, it appears you did declare that element:

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

So, what's the problem?

The problem is you have declared it locally. What it actually means is that, according to your schemas, your <staff> element can be valid only as a child of <Company> element. It must not be found anywhere else!

However, in your XML:

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

you do want to use <stuff> also as a child of <Product>, which is not provided by your schema.

The XML validator doesn't say that your <stuff> element cannot be used within <Product> because it is local child of <Company>. To it, the local element is determined by the path:

Company/stuff

When it finds <stuff> within <Product>, it looks for a path:

Company/Product/stuff

which is unknown to it. Then, it just says it cannot find a declaration for <stuff>. It doesn't analyze further what you might have done wrong.

So, the problem is actually not about namespaces but about locally declared elements. You should redesign your schemas to fix it!



来源:https://stackoverflow.com/questions/17173766/allowing-any-elements-from-a-particular-namespace-with-two-schemas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!