While looking at XML schema examples, I have seen the following case (in xml schema test suite, microsoft schema schG1_a/b/c.xsd):
Conceptually, schema document A (target a) imports schema document B (target b) which in turn imports schema document C (target c).
My reading of the schema specs is that A must directly import C in order to refer to anything in C (import is not transitive). It does not. This is not an issue because A itself does not refer to anything in C or even in B. It defines just an element 'root' that is a sequence of 'any' from '##any' namespace with processContents 'strict'.
Now the problem is that the instance document schG1.xml is referring to the schema A only although it uses global elements defined in A, B and C as children of the 'root' element in A. Because processContents is 'strict' the schema A should be used to validate the instance elements (as children of 'root'). I understand that it can do it for the elements defined in A and B (directly imported in A) but I fail to understand how it can validate elements from C since they were never directly seen in A.
However the test is supposed to be valid. I am sure I must be missing something...
schG1_a.xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="ns-a" xmlns="ns-a">
<xsd:import namespace="ns-b" schemaLocation="schG1_b.xsd"/>
<xsd:element name="e1" type="xsd:int"/>
<xsd:element name="root">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:any namespace="##any" processContents="strict"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
schG1_b.xsd
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="ns-b" xmlns="ns-b">
<xsd:import namespace="ns-c" schemaLocation="schG1_c.xsd" />
<xsd:element name="e1" type="xsd:boolean" />
</xsd:schema>
schG1_c.xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="ns-c" xmlns="ns-c">
<xsd:element name="e1" type="xsd:string" />
</xsd:schema>
schG1.xml:
<a:root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="ns-a schG1_a.xsd"
xmlns:a="ns-a" xmlns:b="ns-b" xmlns:c="ns-c">
<a:e1>123</a:e1>
<b:e1>true</b:e1>
<c:e1>foo</c:e1>
</a:root>
Related
I have an xsd with annotation elements that in turn contain the appinfo element. I am using the appinfo element to pass in the some custom information about the schema and need to extract the contents of the appinfo while I am traversing through the element.
Snippet from the xsd.
<xsd:element name = "Entity">
<xsd:annotation>
<xsd:appinfo>EntityReference</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element
minOccurs = "0"
name = "Id"
type = "tns:guid"/>
<xsd:element
minOccurs = "0"
name = "LogicalName"
nillable = "true"
type = "xsd:string"/>
<xsd:element
minOccurs = "0"
name = "Name"
nillable = "true"
type = "xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
This is the code that I am using to extract the application information from the annotation.
SchemaAnnotation annotation = element.getAnnotation();
if(annotation!=null){
XmlObject[] ai = annotation.getApplicationInformation();
for(XmlObject obj : ai){
if(obj!=null){
//System.out.println(obj.toString());
obj.getDomNode().getNodeValue();
}
}
}
But I get a null value. The obj.toString() however returns this
<xml-fragment xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:request="http://ns1" xmlns:tns="http://ns2">EntityReference</xml-fragment>
How do I get the content "EntityReference" from appinfo? Am I suppose to write a custom handler to parse the string content?
Thanks
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(obj.toString().getBytes()));
NodeList list = document.getChildNodes();
Node node = list.item(0);
if (node.getFirstChild() != null
&& node.getFirstChild().getNodeType() == Node.TEXT_NODE) {
//Text tn = (Text) node.getFirstChild();
System.out.println(node.getFirstChild().getTextContent());
}
I have the schema like this :
<xsd:complexType name="ContentType" mixed="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
The content type is a broad base type allowing any content.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="BaseContentType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"
/>
</xsd:sequence>
<xsd:attribute name="orientation" type="OrientationEnum" use="optional"
default="portrait">
<xsd:annotation>
<xsd:documentation><![CDATA[
The #orientation attribute is used to specify a "landscape"
orientation for the published form. This is primarily used
for schedules or for tables.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
I use xjc command line tool to generate the Java classes from the above schema and the classes are generated as follows:
public abstract class BaseContentType {
#XmlMixed
protected List<Serializable> content;
#XmlAttribute(name = "id")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
#XmlID
#XmlSchemaType(name = "ID")
protected String id;
and
public class ContentType
extends BaseContentType
{
#XmlMixed
#XmlAnyElement(lax = true)
#OverrideAnnotationOf
protected List<Object> contentOverrideForContentType;
When I unmarshall, all the nested xml elements get populated in the List contentOverrideForContentType of the ContentType object and all the text elements get populated in the List content of BaseContentType.
How do I determine the order of the text elements with respect to the nested elements and construct the entire text?
I am trying to get the entire text within the ContentType for which I have to look at top level text and the text of all the nested tags and combine them all(here is where I need to know the order). Is there a better way to just extract all the text from ContentType?
Thanks!
EDIT
This is related to this question.
If you declare a propOrder on the specific jaxB class you can specify the order that objects will appear in the xml
e.g.
#XmlType(propOrder = {
"firstObjectName",
"fsecondObjectName"
})
note: when using a propOrder all elements in the object must be added to the propOrder.
I had the same issue and I found out that the elements will be ordered following the order in which the elements had been added to the list ... this is assuming you are using an ordered list (List, ArrayList...)
1.
<xsd:element name="tuple">
<xsd:complexType>
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="skip" />
</xsd:sequence>
</xsd:complexType>
2.
<xsd:element name="tuple"/>
Are the both above schemas equivalent?
Please help
NO! They aren't same!
In first schema: element <tuple> can have 0 or more elements under it with/of any name, that is because you have added <any> tag with minOccurs="0" and maxOccurs="Unbounded" under complexType definition of element tuple
Also Since you have specified processContents="skip" under <any> it doesn't bother anything about its child elements..
Example:
<tuple>
<foo>data</foo>
<bar foobarattribute="foobardata">data</bar>
</tuple>
As you can see, though foo and bar and its attribute foobarattribute are not defined in XSD, it allows this XML as valid. But it doesn't allow attribute under <tuple>
EDIT:
Second schema:
It is as same as declaring the type as anyType
<xsd:element name="tuple" type="xs:anyType"/>
Which means it allows any element and any attribute under tuple. The sample XML would be like:
<tuple foo="bar">
<foobar attrb="value">data</foobar>
</tuple>
You can observe that unlike first sample XML, this has attribute under <tuple> as well.
One more important difference between two sample XSD code is:
In 1st code you are specifying processContents as "skip": Because of which XML processor does not attempt to validate any elements from the specified namespaces..
In the 2nd Code, for anyType, processContents would be "lax": because of which the XML processor tries to obtain the schema for the required namespaces and validate the elements.
Hope it helps..
We are using schemagen to create an XSD from some annotated POJOs.
Here is our ant target
<target name="generate-xsd" depends="compile">
<taskdef name="schemagen" classname="com.sun.tools.jxc.SchemaGenTask"
classpathref="xjc.classpath"/>
<schemagen srcdir="src" destdir="generated" includeantruntime="false">
<include name="com/acme/exam/delivery/records/**"/>
<schema namespace="http://www.acme.com/deliverylog"
file="deliverylog.xsd"/>
<schema namespace="" file="supplemental.xsd"/>
</schemagen>
</target>
This is generating
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://www.acme.com/deliverylog"
xmlns:tns="http://www.acme.com/deliverylog"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Where does the tns namespace come from and what does it signify?
That infomration comes from the package level annotation #XmlSchema which can be found in the package-info class. See below for an example.
package-info
#XmlSchema(
namespace = "http://www.acme.com/deliverylo",
elementFormDefault = XmlNsForm.QUALIFIED)
package example;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Sample XML
elementFormDefault specifies which elements should be namespace qualified (true = all, false = only global elements), and targetNamespace defines what the namespace is.
<foo xmlns="http://www.acme.com/deliverylog">
<bar>Hello World</bar>
</foo>
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
Suppose I have an XSD file having below lines of code;
<xsd:simpleType name="test">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
What I am trying to do is to convert this xsd simple type into an instance of rdfs:Datatype in an ontology. Below is what I want.
<rdfs:Datatype rdf:about="http://www.example.org/example1/#testDatatype">
<rdfs:subClassOf rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<owl:equivalentClass>
<rdfs:Datatype>
<owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<owl:withRestrictions rdf:parseType="Collection">
<rdf:Description>
<xsd:maxLength rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
>50</xsd:maxLength>
</rdf:Description>
</owl:withRestrictions>
</rdfs:Datatype>
</owl:equivalentClass>
</rdfs:Datatype>
How do I do this using Jena?
Turns out I can do this with the below code. I parse XSD with XSOM. Assume that I stored "test" simpletype in a variable called "simple" (XSSimpleType).
String URI = simple.getTargetNamespace() + "#" + simple.getName() + "Datatype";
OntModel ontology = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
OntClass datatype = ontology.createOntResource(OntClass.class, RDFS.Datatype, URI);
Resource onDatatype = XSD.xstring;
OntClass equivClass = ontology.createOntResource(OntClass.class, RDFS.Datatype, null);
equivClass.addProperty(OWL2.onDatatype, onDatatype);
datatype.addEquivalentClass(equivClass);
It is not a complete code and it does not include the code segment related with parsing XSD but I hope it will give the idea.