At the XSD level, can I define an element requirement based on presence of another element in the document?
For example, I want to require the element <firstname /> be provided whenever the <id /> element is also present, otherwise first name is optional.
If this cannot be enforced at the XSD level, then should I make both elements optional and enforce the requirement through a different level of checking?
Options welcome.
This cannot be enforced at the XSD level.
Making both elements optional and enforcing the requirement at a different level in the application architecture sounds like a good option to me.
Here's an example of this being done in a DTD. (Note: The test instances were validated using oXygen XML Editor (which is using Xerces).)
DTD (test.dtd)
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT user ((firstname?|(firstname,id)),lastname)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT id (#PCDATA)>
Here are some example XML instances (valid and invalid):
Valid
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE user SYSTEM "test.dtd">
<user>
<firstname/>
<id/>
<lastname/>
</user>
Invalid
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE user SYSTEM "test.dtd">
<user>
<id/>
<lastname/>
</user>
Valid
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE user SYSTEM "test.dtd">
<user>
<firstname/>
<lastname/>
</user>
Related
Does any XSD edge case allow (unescaped) XML element content inside a text node? E.g. can you put a CDATA element inside a tag defined as xs:string and have it validate (without declaring mixed content)?
If you have an element that contains a string i.e.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2018 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root" type="xs:string" />
</xs:schema>
Then that can contain CDATA i.e.
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2018 (https://www.liquid-technologies.com) -->
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\Temp\XSDFile2.xsd">
Optional Text
<![CDATA[
<someXmlData></someXmlData>
]]>
Optional Text
</Root>
As this passes though some parsers it may get escaped back to this, but both are valid and equivalent.
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2018 (https://www.liquid-technologies.com) -->
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="XSDFile2.xsd">
Optional Text
<someXmlData></someXmlData>
Optional Text
</Root>
I am seeing some XSD schema documents that declare both a targetNamespace and an xmlns:tns attribute in their top schema element. E.g. the following one taken from here. They also seem to have the same string value. I understand the role of targetNamespace but what does xmlns:tns do on top of that?
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/Product"
xmlns:tns="http://www.example.org/Product"
elementFormDefault="qualified">
...
It lets you refer to the namespace later in the schema. For example, if you declare a named type and then want to also declare an element of that type
<complexType name="someType">
<!-- ... -->
</complexType>
<element name="someElement" type="tns:someType" />
Simply saying type="someType" wouldn't work because that would be referring to the (non-existent) someType in the http://www.w3.org/2001/XMLSchema namespace (the xmlns="..." of the schema file) rather than the one in the http://www.example.org/Product namespace.
I have a problem, I have an XSD file which I am trying to validate with an XML:
The XSD starts with:
<xs:schema id="Notes"
targetNamespace="http://mynotes.com/Notes"
elementFormDefault="qualified"
xmlns="http://mynotes.com/Notes"
xmlns:mstns="http://mynotes.com/Notes"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Then I have the following XML:
<?xml version="1.0" encoding="utf-8"?>
<notes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="noNamespaceSchemaLocation" xmlns="http://mynotes.com/Notes">
In that case I can validate, but when I use JAXB to create an objects, the objects don't get populated and all their members are null.
But, If I modify the XML to the following:
<?xml version="1.0" encoding="utf-8"?>
<notes>...
In this case the JAXB objects are created successfully, but the validation fails...
I guess I am missing something with the namespace declaration, your help will be highly appreciated.
Thanks.
You can use the package level #XmlSchema annotation to specify the default namespace qualification for your JAXB model. Below is an example, you will need to adjust the package to be the same as your domain classes.
com/example/package-info.java
#XmlSchema(
namespace = "http://mynotes.com/Notes",
elementFormDefault = XmlNsForm.QUALIFIED)
package com.example;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
I have an XML which looks like below in which the numbers of Items can vary from 0 to n. Is there a way to write XSD for verifying the Schema .
<?xml version="1.0" encoding="utf-8" ?>
<ShoppingItems>
<CustomerName>John</CustomerName>
<Address>Walstreet,Newyork</Address>
<Item1>Milk</Item1>
<Price1>1$</Price1>
<Item2>IceCream</Item2>
<Price2>1$</Price2>
<Item3>Bread</Item3>
<Price3>1$</Price3>
<Item4>Egg</Item4>
<Price4>1$</Price4>
<Item..n>Egg</Item..n>
<Price..n>1$</Price..n>
</ShoppingItems>
Not in it's current form. An XSD definition is very strict - in the above case you would have specify every possible ShoppingItems type (those including Item..n and Price..n) which is of course not possible.
What would be better is to change the XML file so that it is more logically structured:
<?xml version="1.0" encoding="utf-8" ?>
<ShoppingItems>
<CustomerName>John</CustomerName>
<Address>Walstreet,Newyork</Address>
<Items>
<Item price="1$">Milk</Item>
<Item price="3$">IceCream</Item>
<Item price="1$">Bread</Item>
<Item price="1.5$">Egg</Item>
</Items>
</ShoppingItems>
It is now completely possible to define this document with a schema.
today i've bumped in the following problem. I have the following xml:
<c:docschema xmlns:c="http://www.otr.ru/sufd/document/desc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.otr.ru/sufd/document/desc http://otr-sufd/xmlschema/docschema.xsd">
...
</c:docschema>
And it's validating fina against it's schema. But I don't want namespace prefixes in my xml, so i try to write it like this:
<docschema xmlns="http://www.otr.ru/sufd/document/desc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.otr.ru/sufd/document/desc http://otr-sufd/xmlschema/docschema.xsd">
...
</docschema>
And it's giving me a validation error. My XSD schema i'm validating against is compound of two XSD's, here is the headers:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="unqualified"
xmlns="http://www.otr.ru/sufd/document/desc"
targetNamespace="http://www.otr.ru/sufd/document/desc"
xmlns:fieldset="http://www.otr.ru/sufd/document/fieldset"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore">
<xsd:import namespace="http://www.otr.ru/sufd/document/fieldset" schemaLocation="fieldset.xsd"/>
and
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="http://www.otr.ru/sufd/document/fieldset"
xmlns="http://www.otr.ru/sufd/document/fieldset">
What's wrong there?
EDIT: The question is now, how to change my XSD's in order to make instance document valid?
Given what you write, I imagine that the problem is the following.
Let's consider that there is an a element under your root element.
This first example below is valid because a is unqualified and because you set elementFormDefault to unqualified :
First example
<c:docschema xmlns:c="http://www.otr.ru/sufd/document/desc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.otr.ru/sufd/document/desc http://otr-sufd/xmlschema/docschema.xsd">
<a>...</a>
</c:docschema>
In the second example the file is not valid because you set elementFormDefault to unqualified and you have an element a that is qualified (in the default namespace) :
Second example
<docschema xmlns="http://www.otr.ru/sufd/document/desc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.otr.ru/sufd/document/desc http://otr-sufd/xmlschema/docschema.xsd">
<a>...</a>
</docschema>
The correct XML could be :
<docschema xmlns="http://www.otr.ru/sufd/document/desc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.otr.ru/sufd/document/desc http://otr-sufd/xmlschema/docschema.xsd">
<a xmlns="">...</a>
</docschema>
EDIT
If the children of the root element are defined in the same namespace than the root in your schemas, you just have to change elementFormDefault="unqualified" to elementFormDefault="qualified" to have a schema that validates the XML. If it's not the case : you will surely have to reshape your schema more deeply, in this case, maybe you should post another question dedicated to that with more code (including more part of the schemas and instances).
Looks like you are making the mistake of assuming that the nested elements inside your root <docschema> will inherit the namespace defined on that root. They will not.
If you want to get rid of namespace prefixes you will then have to explicitly declare the namespace at every sub-node in your instance document.
Eg
<Root xmlns="http://www.myns.com">
<MyElement1 xmlns="http://www.myns.com">
... etc
</MyElement1>
</Root>
or
<p:Root xmlns:p="http://www.myns.com">
<p:MyElement1>
... etc
</p:MyElement1>
</p:Root>
Which is nicer? I think the second option.