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