xml


XSD 1.1 - Alternative Test Xpath on Child Element


Im trying to use the XSD 1.1 framework to test that the child element of the current scope element contains an attribute. If true I want one schema validation for the element, if false i want another.
Example XML
<!-- XML 1 -->
<GrandParent name="Sam">
<Parent name="Kevin">
<Child name="Kyle" id="10" dob="1989-05-02"/>
</Parent>
</GrandParent>
<!-- XML 2 -->
<GrandParent name="Sam">
<Parent name="Kevin" id="10" dob="1975-10-11"/>
</GrandParent>
XSD 1.1 used for above xml examples
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:element name="GrandParent">
<xs:complexType>
<xs:sequence>
<xs:element ref="Parent" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="Parent">
<xs:alternative test="./Child/#id" type="ParentType1" />
<xs:alternative type="ParentType2" />
</xs:element>
<xs:element name="Child">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="id" type="xs:integer" use="required" />
<xs:attribute name="dob" type="xs:date" use="required" />
</xs:complexType>
</xs:element>
<xs:complexType name="ParentType1">
<xs:sequence>
<xs:element ref="Child" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="ParentType2">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="id" type="xs:integer" use="required" />
<xs:attribute name="dob" type="xs:date" use="required" />
</xs:complexType>
</xs:schema>
Im using Xerces xsd 1.1 validation functionality
XSD Validation Error
XML 1
[Error] 1:46: cvc-complex-type.4: Attribute 'id' must appear on element 'Parent'.
[Error] 1:46: cvc-complex-type.4: Attribute 'dob' must appear on element 'Parent'.
[Error] 1:100: cvc-complex-type.2.1: Element 'Parent' must have no character or element information item [children], because the type's content type is empty.
XML 2
Validates
The Xpath doesn't seem wrong to me, i've tried a few variations including //Child/#id and boolean(Child/#id) but no joy. I dont care what the value of the attribute is, only that it exists in the child element.
Update
Thanks to the answer below provided by Michael Kay, I rewrote my schema use asserts instead of alternatives. Here is the updated schema:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="GrandParent">
<xs:complexType>
<xs:choice>
<xs:element ref="Parent" />
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="Child">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="id" type="xs:integer" use="required" />
<xs:attribute name="dob" type="xs:date" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="Parent">
<xs:complexType>
<xs:sequence>
<xs:element ref="Child" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="id" type="xs:integer" use="optional" />
<xs:attribute name="dob" type="xs:date" use="optional" />
<xs:assert test="if (Child/#id) then not(#id or #dob) else (#id and #dob and not(Child))"/>
</xs:complexType>
</xs:element>
</xs:schema>
The schema seems to work much better, I tested it with the following XML all of which passed or failed as expected
PASS <GrandParent name="Sam"><Parent name="Kevin"><Child name="Kyle" id="10" dob="1989-05-02"/></Parent></GrandParent>
PASS <GrandParent name="Sam"><Parent name="Kevin" id="10" dob="1975-10-11"/></GrandParent>
FAIL <GrandParent name="Sam"><Parent name="Kevin" id="10"/></GrandParent>
FAIL <GrandParent name="Sam"><Parent name="Kevin" dob="1975-10-11"/></GrandParent>
FAIL <GrandParent name="Sam"><Parent name="Kevin"/></GrandParent>
The condition tests in a type alternative construct can only access attributes of the element in question, not children or descendants.
The way this is achieved in the spec is by defining that the XPath expression is evaluated against a data model instance constructed as a shallow copy of the element being validated, where the shallow copy includes copies of attributes but not of children. As a result, attempting to access a child doesn't give an error, it just gives false.
The reason for the restriction is to avoid the problems that could occur if you have to look at invalid data in order to determine whether it is invalid: you can easily end up with a liar's paradox.
For this validation you need the more general capability of assertions, rather than type alternatives.

Related Links

rearranging of XML elements and extracting relevant data from its values
XML Interpreter
XML UTF-8 encoding what is the correct way to represent the non-ascii data
XLINQ: string vs Convert.ToString() when extracting element values
Scala, combining filters on XML node
XML digital signature - wrongly computed digest
Zoho API inserRecord using Curl and XML, not returning an error and not adding the “Potential”
Magento - Move cart dropdown plugin to top.links. Reference name=“top.Links” not changing location
Read an include file using XSL
Convert flat xml string to tree structure
Why is JSON more lightweight than XML?
Adding a Large XML Element to an XML File Always Fails
How to extract day-of-the-week from datetime format from XML document
How to convert rows of a database query to a XML file?
convert string in to encoded xml document
Merge 2 XML files with matching 'id' attribute using XSLT

Categories

HOME
grok
awk
angular2-material
zend-framework
toolbox
components
regular-language
bookmarks
settings
tvos
android-json
google-cloud-datalab
trac
pattern-matching
g++
redis-sentinel
ipmitool
gkturnbasedmatch
aws-sdk
intershop
red5
forgot-password
google-container-registry
sse
boost-icl
displaytag
slidetoggle
amazon-quicksight
datastax-enterprise-graph
boost-asio
event-flow
scatter3d
record
android-sugarorm
getpixel
reactjs.net
fossil
nested-lists
reverse
searchkit
openerp-7
connection-pool
sim-card
unordered-map
resolution
trigonometry
attributeerror
android-ibeacon
preloader
chronicle-map
importerror
oim
jide
serde
opengl-4
skin
bbpress
flac
template-toolkit
google-photos
actor-platform
centrifuge
mta
beamer
gogs
udpclient
php-socket
spreadjs
dbamp
hadoop-partitioning
invoke-sqlcmd
user-management
character-replacement
toran-proxy
ember-cli-rails
branch-and-bound
skspritenode
mass-assignment
android-vibration
paw
tweenlite
personalization
amslidemenu
git-repo
mysql-error-1044
hidapi
joomla-template
composite-component
onmousemove
nokia-s40
lambdaj
agility.js
gobject-introspection
matlab-load
catransform3d
aspmenu
addchild
sifr
skype4java
silverlight-oob
lobo-cobra
tui
cardspace
great-circle

Resources

Encrypt Message