1
votes

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

2 Answers

0
votes
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.
1
votes

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.