How to define elements with any name but enforce specific attributes? - xsd

I have an XML that contains such definition:
<addr15 type="binary" size="1" data_characters="0,1,0,1">text 15</addr15>
<addr14 type="binary" size="1" data_characters="0,1,0,1">text 14</addr14>
<addr13 type="binary" size="1" data_characters="0,1,0,1">text 13</addr13>
<addr12 type="binary" size="1" data_characters="0,1,0,1">text 12</addr12>
<addr11 type="binary" size="1" data_characters="0,1,0,1">text 11</addr11>
As the elements' names are user defined (any valid string is ok), the attributes are mandatory.
How can I define an XSD to validate this?
Using <xsd:any> won't do the job - it can't validate the attributes.
Set processContents to lax or strict won't do the job also, as I can't supply the required XSD statements to validate.

the elements' names are user defined (any valid string is ok)
An XSD mainly describes the tag names in the document, and how they can be validly combined. So this XML format is going to be tricky to describe using an XSD.
Options (in order of my preference):
Change the tag name to <addr> and define a new required attribute 'addrNumber' to hold the 11,12,13,14,15. This would be easy to describe using an XSD.
Pre-declare all of the allowed <addrNN> tag names as global elements in your XSD. Disallow any tag names that are not pre-declared in the XSD (advanced users could add their own declarations to the XSD)
Continue to allow user-defined tag names. Define a global complex-type-with-simple-content that describes the attributes and the tag value. Every user-defined <addrNN> tag must include an xsi:type attribute that points to this global type. I think this will require an xsd:any with processContents='strict' to ensure that the xsi:type attribute gets strictly validated.
I will not go into details on each option, but I can supply further details if you need them.

Related

How to allow any attributes from unknown namespaces?

I'm writing an XML Schema. It validates elements and their attributes from a single namespace.
How do I allow any attributes from other namespaces while still validating the non-prefixed attributes?
The list of other attributes and their namespaces is unknown at the time of writing the schema.
The XML is human-written and I would like to minimize the possibility of typos in attribute names. The attributes from other namespaces will used scarcely so it's ok not to validate them.
<xsd:anyAttribute namespace="##other" processContents="lax" />

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.

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/

An XSD attribute to capture "source data field"

I have a domain model which is intended to generalise several source systems. As such, in certain cases the decision was made to overload data into new a generic field rather than to create several specific fields.
To account for this, when the source systems data is mapped onto the new domain model, I was hoping to record the source fieldname as an attribute, e.g.:
<Event>
<Description sourceField="subject">...</Description>
<Description sourceField="description">...</Description>
<Description sourceField="issue">...</Description>
<...>
</Event>
What would be the appropriate way to add such an attribute into the XSD? Would I need to specifically attach it to every such overloaded field, or is there a general way to allow an attribute across all elements?
Please don't point out that I should just add the extra fields into the domain model if I need to distinguish between the different data - the decision has been made, I just need to work around it!
Thanks in advance.
Not really.
If all your element declarations extend from a common base type definition, then you can add the attribute to the base.
If all your element declarations include an anyAttribute, you can make a global attribute definition for sourceField. Then the validator would at least allow your attribute but not require it. And if the anyAttribute is strict or lax the validator will make sure the attribute's content is valid.

XML Schema: How to validate an attribute with multiple keys concatenated?

Let's say I can get XML like this:
<Property Name="Title"/>
<Property Name="Content"/>
<Property Name="Address"/>
<Source properties="Title,Content,Address"/>
How coud I validate the "properties" attribute of "Source", so that any composition of the above listed "Property" items could be checked? (For example: "Title", "Title,Content", all of these concatenations are correct, while "Title, URL" is not correct.)
You can't do that within XML Schema. You can do it with your own higher level of validation based on XSLT, XQuery or Schematron, for example.
xan is right; validating always means, to match a XML file against a given schema. But there is no schema involved here, your problem is instead, to read a data file, and validate later entries against earlier ones (if the box above is supposed to represent one file) or one data file against another data file (if the gap is supposed to be a file separator). Beyond that, a schema defines the structure of elements and attributes and optionally data types (values only, if there is a strict enumeration of valid values). Also no match here, instead you want to verify data against data. Sorry, the tool of a schema mismatches the problem to solve.

Resources