質問

Basically my question is whether or not there is way to validate a non-root element according to a given XSD schema.

I am currently working on some legacy code where we have some C++ classes that generate XML elements in string format.

I was thinking about a way to unit test these classes by verifying the generated XML (I'm using Xerces C++ under the hood). The problem is that I can't reference an element from another schema different from the root.

This is a more detailed description of what I'm doing:

I have a class called BooGenerator that generates a 'booIsNotRoot' element defined in 'foo.xsd'. Note that 'boo' is not the root element :-)

I have created a test.xsd schema, which references 'booIsNotRoot' in the following way:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://acme/2014/test"
            xmlns:foo="http://acme/2014/foo"
            targetNamespace="http://acme/2014/test"
            elementFormDefault="qualified">
  <xsd:import namespace="http://acme/2014/foo" schemaLocation="foo.xsd"/>
  <xsd:complexType name="TestType">
    <xsd:choice minOccurs="1" maxOccurs="1">
      <xsd:element ref="foo:booIsNotRoot"/>
    </xsd:choice>
  </xsd:complexType>
  <xsd:element name="test" type="TestType"/>
</xsd:schema>

Then I wrap the string generated by BooGenerator with a test element:

<test xmlns="xmlns="http://acme/2014/test"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:foo="http://acme/2014/foo
      xsi:schemaLocation="http://acme/2014/test test.xsd">
  (code generated by BooGenerator prefixed with 'foo')
</test>

but as I said before it doesn't work. If I reference the root element in foo.xsd it works. So I wonder if there is a way to work around this.

Thanks in advance.

役に立ちましたか?

解決 2

Basically my question is whether or not there is way to validate a non-root 
element according to a given XSD schema.

Theoretically speaking, yes, Section 5.2 Assessing Schema-Validity of the XSD Recommendation allows for non-root element validity assessment. (Credit and thanks to C. M. Sperberg-McQueen for pointing this out.)

Practically speaking, no, not directly. XML Schema tools tend to validate against XML documents — not selected, individual elements — and XML documents must have a single root element. Perhaps you might embed the element you wish to validate within a rigged context that simulates the element's ancestry up to the proper root element for the document.

If I reference the root element in foo.xsd it works.

The root element in foo.xsd had better be xsd:schema, actually. You probably mean to say

If I reference an element defined globally (under xsd:schema) in foo.xsd it works.

That is also how @ref is defined to work in XML Schema — it cannot reference locally defined elements such as foo:booIsNotRoot. Furthermore, any globally defined element can serve as a root element. (In fact, only globally defined elements can serve as a root element.)

So, your options include:

  1. Rig a valid context in which to test your targeted element.
  2. Make your targeted element globally defined in its XSD.
  3. Identify an implementation-specific interface to your XSD validator that provides element-level validation.

他のヒント

Yes, it's entirely possible. XSD validation is defined as starting at some node in an XML document and validating it (which normally entails validating all of its descendants), so a request to validate a particular element against a specified element declaration or type definition is perfectly coherent.

How you go about conveying such a request to an XSD validator is implementation-specific (and XSD does not prescribe a particular API or command-line interface, so conforming XSD validators are not obligated to support all of the methods of starting a validation episode defined in section 5.2 of the XSD spec); you will have to consult the implementation's documentation. I believe the most common way of supporting such validation is to call a method in the implementation's XSD library with appropriate XML element, schema, and type definition or element declaration objects. I have not seen any command-line interfaces to XSD validators that support starting validation elsewhere than at the root.

A very late answer, but schema-aware XSLT and XQuery both have ways of validating an arbitrary element.

In XSLT, <xsl:copy-of select="//some-element" validation="strict"/>.

In XQuery, validate strict {//some-element}.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top