Element dependency on sibling element value - xsd

I need to define a validation rule under XML Schema 1.0 that allows an element to occur (once) among a set of sibling elements only if another specific sibling has a certain value.
For example, given the instance XML document snippet,
<root>
<parent>
<child1>A</child1>
</parent>
<parent>
<child1>B</child1>
<chlld2>C</child2>
</parent>
</root>
I'd like the rule to allow the child2 element to occur only if the required child1 element has a value of 'B', otherwise, the child1 element should occur by itself under a given parent.
This is quite easy to achieve under XML Schema 1.1 using an xs:assert, but the solution under version 1.0 evades me.
Any insights are most appreciated.

The usual approach in XSD 1.0 is to design the XML differently: if we have one particular value B for child1 which makes the occurrence of child2 possible, then we can split child1 into two element types: child1-notB and child1-B. And since in the case of child1-B we know the value, the value doesn't actually need to be present. The XML becomes:
<root>
<parent>
<child1-notB>A</child1-notB>
</parent>
<parent>
<child1-B/>
<chlld2>C</child2>
</parent>
</root>
It's simple to write a content model in which the parent element contains either a child1-notB or a child1-B followed by an optional child2.
As Dijkgraaf has already observed, the specific design you describe cannot be expressed in XSD 1.0. XSD 1.1 added assertions in part because so many people want designs like the one you describe, in which two quite different elements, which have quite different effects on what is and is not allowed, are nevertheless given the same name so as to mask their difference in meaning, instead of being called by different names to make their difference in semantics explicit.

Related

XSD Verify attribute is set on only one element

I have a pre-existing XML that I'm writing a XSD for. The relevant section is basically:
<color a='1' default='true'>Red</foo>
<color a='2'>Yellow</foo>
<color a='3'>Blue</foo>
I want to validate that only one of the foo elements has an attribute default='true'. Note the other elements can either have default='false' or not have it at all (in which case it defaults to false).
I tried to use a key but it doesn't work in the example above because there's multiple default='false' values which is not unique.
Can such validation be done with XSD 1.0?
(I can't change the XML format unfortunately.)
Can such validation be done with XSD 1.0?
No. I suspect that XSD 1.1 could do it, but 1.0 defintely cannot.

Making subtags dependent on an attribute of a parent in XML Schema

I have created an XML file like the following
<monitor>
<widget name="Widgets/TestWidget1">
<state code="VIC" />
<state code="TAS" />
</widget>
<widget name="Widgets/TestWidget2">
<client code="someclient" />
</widget>
</monitor>
The name attribute of the <widget> tag tells the parser what widget to load (they are asp.net user controls).
I am trying to create a schema file for the above, the problem is that inside the <widget> the supported subtags are dependent on the name attribute. So TestWidget1 supports the <state> tag and TestWidget2 supports the <client tag.
Currently my XML Schema file just displays all possible <widget> subtags regardless of whether they are supported or not.
How can I write an XML schema file that will only allow specific subtags based on the name attribute? If this is not possible, what options do I have?
You have several options. The simplest and most direct is to re-think your problem a bit. If the legal content of element E1 and the legal content of element E2 are different, then the simplest design is to call them different things, because in XSD as in DTDs the legal content of an element depends on the element type name. A devil's advocate would ask you "if you want different kinds of widget to obey different rules, why are you telling the validator that they are the same kind of widget? Tell the validator the truth, by giving them different names. So don't call them and so on, call them and ."
In XSD 1.1 you can also use conditional type assignment or assertions to define constraints on the legal combinations of attributes and children, but not every schema-aware editor is going to have the chops necessary to analyse the conditional type assignment rules and attributes and understand what to prompt you with.

JAXB and XSD: element, complexType by attribute value

My XML file has root element and then many item elements as root's children.
So it looks like this:
<root>
<item type=type1 id=1>...</item>
<item type=type1 id=2>...</item>
<item type=type2 id=3>...</item>
<item type=type3 id=4>...</item>
</root>
Every item element has attribute that says what type of item we are dealing with.
In current XSD
xs:element name="root" is as complexType which has sequnce of item complexType.
I'm using JAXB to map my XML file to Java objects. Now I have to get all items and according to their types, create new, specific object. It get more and more complicated, as each item type has its own set of fields (child nodes). Is there any chance I can tell JAXB (by XSD) that there are different types of items and according to item's name attribute create object which I need? So for each item there should be separate complexType (which would be mapped to java object).
It would be all ok if my XML looked like this:
<root>
<item1 id=1>...</item1>
<item1 id=2>...</item1>
<item2 id=3>...</item2>
<item3 id=4>...</item3>
</root>
If you can change the XML so that instead of the unqualified type attribute you can have a qualified type attribute xsi:type (xsi is the prefix associated with the XML Schema Instance namespace) then:
your schema needs to provide definitions for those types
That would be it...
If you can't (worth a try) maybe this post on SO could help you.

Require that an element has another element as a descendant

Is there a way in an xsd schema to require that an element have another element somewhere as a descendant?
For example, element parent requires a descendant desc. This is valid:
<parent>
<a>
<b>
<desc></desc>
</b>
</a>
</parent>
As is this:
<parent>
<c>
<desc></desc>
</c>
</parent>
but this isn't:
<a>
<parent>
<b/>
</parent>
</a>
The potential child elements for parent are many and complicates, so it would be difficult to enumerate every possible valid configuration.
Something like the key/selector schema elements seems like it would work, where I could provide an xpath expression defining the valid locations for desc element, but all of the examples I've found are aimed at matching up the value of attributes.
No, (almost) all XML Schema validation is shallow, called "local" in the spec. Here's one excerpt that emphasizes type validation as "local" validation.
Element Validated by Type If an
element information item is ·valid·
with respect to a ·type definition· as
per Element Locally Valid (Type)
(§3.3.4), [it is marked as] ·validated·.
The only exception is for the identity constraints like uniqueness and key-references which have a broad scope in an XML document but narrow uses.
I don't know if XSD supports what you are trying to do, but there is a work-around.
You could do complex validations with a two-step process:
First simply use your XSD schema for basic validation
Next use an XSLT which does more complex validations, and outputs the result of that validation
This may not plug in well to whatever framework you are working with, but might work well for (partially) custom code. It also has the advantage (over doing the extra validations in code) that you can publish both documents.
From a quick google search, one effort towards this end is Schematron. It actually foregos XSD entirely, and just uses XSLT. It appears to be a published standard:
http://www.schematron.com/

Given an XSD is it possible to list a hierarchy of elements and their attributes?

Lets pretend I have an XSD document and I want to produce a list of all elements along with their attributes and the children of the elements. I could also approach this by asking if you are to implement code completion based on an xsd document, and you want to list the children of the element and an elements attributes, how would you approach this problem?
Since XSD is valid XML document it just a matter of selecting XML parsing library of your choice. For example XLinq (.NET FW 3+) will do the job.
You can just walk through complexType, sequence and other elements to find out a list of possible values.

Resources