XML schema: how to allow one particular element anywhere?

This should cover W3C XML Schema, Relax NG and DTD related problems.
MarcSharma
Posts: 1
Joined: Thu May 24, 2018 1:39 pm

XML schema: how to allow one particular element anywhere?

Post by MarcSharma »

I have a `xml` file that is basically the data of an article. I want to write a `xml schema` to validate that file. In the xml article's file, I have used a few tags in the middle of text, for instance:

Code: Select all

<p>The dog is <em>brown</em><p>
I use that `em` tag elsewhere as well, inside other type of elements, so the problem isn't just to allow it inside `p`.

**My question:** how do I allow it to be used inside any elements of my schema?

I did not really understand those answers (I am a beginner), but it seems `openContent` might be the solution I am looking for.

Minimal Working Example:

Code: Select all

    <?xml version="1.0"?>
<doc>
<foo>text <bar /> anything</foo>
<tag>text <bar /> </tag>
</doc>
Schema:

Code: Select all

    <?xml version="1.0"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="subclass">
<xs:complexType>
<xs:sequence>
<xs:element name="foo">
</xs:element>
<xs:element name="tag">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
My real document involves some nested `sequence` and `choice`, and other documents I create will be different, so I am looking for a general solution.

**Optional question:**if the solution does not involve `openContent`, can someone explain me how it works as well? Search results were strangely lacking in example and explanations (for beginners), unlike everything I looked up.
adrian
Posts: 2850
Joined: Tue May 17, 2005 4:01 pm

Re: XML schema: how to allow one particular element anywhere?

Post by adrian »

Hi,
I use that `em` tag elsewhere as well, inside other type of elements, so the problem isn't just to allow it inside `p`.
**My question:** how do I allow it to be used inside any elements of my schema?
There is no such a thing in XML Schema (not even 1.1). You can allow any element from a namespace (or any namespace) to be used in a specific context, but there is no way to specify that a single element can be used anywhere (in any context).
**Optional question:**if the solution does not involve `openContent`, can someone explain me how it works as well? Search results were strangely lacking in example and explanations (for beginners), unlike everything I looked up.
xs:openContent and xs:defaultOpenContent only allow at most interleaved elements (siblings, not children). So these could, in theory, resolve the problem for complex types.
e.g.

Code: Select all

    <xs:complexType name="nameType">
<xs:openContent mode="interleave">
<xs:any namespace="http://myns"/>
</xs:openContent>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="number" type="xs:int"/>
<xs:element name="family" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="elem" type="xs:string"/>
Then 'elem' (which is from the http://myns namespace) is allowed anywhere between the elements of the complex type.
xs:defaultOpenContent does the same at schema level, for all complex types.

If you think about it it's not really possible to do anything like this for elements that have simple or atomic types.
e.g.

Code: Select all

<xs:element name="name" type="xs:string"/>
<xs:element name="number" type="xs:int"/>
How would this work if 'em' would be allowed within these elements?

There is no easy way out for this problem. You have to make significant changes to the schema and convert all types to allow your element. You might actually discover that it shouldn't be allowed everywhere.

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
Post Reply