i'm new to xsd and i want to generate xml like below with STUDENTRECORD occurring multiple times. i'm using jaxb to generate classes on the xsd
<STUDENTDETAIL>
<STUDENTINFORMATION>
<STUDENTRECORD>
<NAME>ABC</NAME>
<CLASS>4</CLASS>
<MAJOR>SCIENCE</MAJOR>
<GRADE>A</GRADE>
</STUDENTRECORD>
<STUDENTRECORD>
<NAME>DEF</NAME>
<CLASS>4</CLASS>
<MAJOR>SCIENCE</MAJOR>
<GRADE>B</GRADE>
</STUDENTRECORD>
</STUDENTINFORMATION>
My current xsd which generates STUDENTRECORD only once.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://webservice.com/WS" targetNamespace="http://webservice.com/WS" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Student" type="Student"/>
<xs:complexType name="Student">
<xs:sequence>
<xs:element name="STUDENTDETAIL">
<xs:complexType>
<xs:sequence>
<xs:element name="STUDENTINFORMATION">
<xs:complexType>
<xs:sequence>
<xs:element name="STUDENTRECORD">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="NAME"/>
<xs:element type="xs:string" name="CLASS"/>
<xs:element type="xs:string" name="MAJOR"/>
<xs:element type="xs:string" name="GRADE"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
Please help to fix.
Thanks
You just need to set a maxOccurs attribute on the STUDENTRECORD element declaration, like this:
<xs:element name="STUDENTRECORD" maxOccurs="unbounded">
This will allow the <STUDENTRECORD> to appear as many times you want. By default a given element is required to appear once.
Similarly, you can set minOccurs attribute to specify the minimal number of occurrences of an element.
Related
I've this XSD Schema definition
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns2="http://www.xxxx.xxxxxxxxx.xxxxxxxx/xxxx/xxxx">
<xs:element name="myRootElemnt">
<xs:complexType>
<xs:sequence>
<xs:element name="messageType">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:short" name="id" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:int" name="time" />
<xs:element type="xs:short" name="date" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The generated XML is:
But, the XML still incomplete, it must contains xmlns:ns2="http://www.xxxx.xxxxxxxxx.xxxxxxxx/xxxx/xxxx"> and the prefix ns2 for the root element , like this:
Any Solutions?
XML
<ns2:Response xmlns:ns2="http://test.com/" Id="122212">
<Infos size="1">
<Info>
<name>test</name>
</Info>
</Infos>
</ns2:Response>
Generated XSD
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document on Mon Feb 20 2017 23:20:03 GMT+0530 (India Standard Time) -->
<!-- with XmlGrid.net Free Online Service http://xmlgrid.net -->
<xs:element name="ns2:Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="xmlns:ns2" type="xs:string"></xs:attribute>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
Error
SAX Exception: s4s-att-invalid-value: Invalid attribute value for
'name' in element 'element'. Recorded reason:
cvc-datatype-valid.1.2.1: 'ns2:Response' is not a valid value for
'NCName'.
There are several changes required for your XML and XSD, including:
Change <xs:element name="ns2:Response"> to <xs:element
name="Response"> because element name declarations must be
non-colonized names (NCNAMEs).
Delete <xs:attribute name="xmlns:ns2".../> because namespaces
cannot be declared as attributes.
Add a targetNamespace to the XSD that matches the namespace of the root element in the XML document.
Import a separate XSD for those elements that you wish to be in no namespace (given that your root elements is in a namespace). You must use a separate XSD to accomplish this.
Altogether, your XML,
<?xml version="1.0" encoding="UTF-8"?>
<ns2:Response xmlns:ns2="http://test.com/"
Id="122212">
<Infos size="1">
<Info>
<name>test</name>
</Info>
</Infos>
</ns2:Response>
will validate successfully against these XSD:
Main
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
xmlns:ns="http://test.com/"
targetNamespace="http://test.com/">
<xs:import schemaLocation="Infos.xsd"/>
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element ref="Infos"/>
</xs:sequence>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
Imported (Infos.xsd)
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
I was able to get a parsed file by, as the above answer suggests, adding a target namepsace to the schema and by adding the ns prefix to all elements.
<?xml version="1.0" encoding="UTF-8"?>
<ns2:Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://test.com testq1.xsd" xmlns:ns2="http://test.com" Id="122212">
<ns2:Infos size="1">
<ns2:Info>
<ns2:name>test</ns2:name>
</ns2:Info>
</ns2:Infos>
and the schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://test.com"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
You can approach this in 2 ways.
Approach 1 - multiple schemas
The more typical approach is to have a schema one for each namespace used.
So you end up with schemas that look like this
SampleXml0.xsd
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
<xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="C:\Temp\StackOverflow\42351409\SampleXml1.xsd" />
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="Infos" />
</xs:sequence>
<xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
SampleXml1.xsd
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="Info">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:unsignedByte" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
Approach 2 - changing elementFormDefault
Now this is quite specific to your example, but as its only the root element that is qualified with a namespace its possible to change elementFormDefault to unqualified. This has the effect of forcing the elements defined as root element in the schema to have a namespace qualification, while the other elements do not.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2017 (https://www.liquid-technologies.com)-->
<xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Info" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:unsignedByte" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
I would probably recommend creating multiple schemas as elementformdefault is typically overlooked by client implementations and ignored.
Why three <xs:sequence> elements? do you really need that? Could you explain better how your code is organized? Usually it is pretty simple, like this:
<xsd:element name="ns2:Response">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xs:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
I have defined following schema for XML
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified"
attributeFormDefault="qualified">
<!-- simple elements -->
<xs:element name="name" type="xs:string"/>
<xs:element name="hod" type="xs:string"/>
<xs:element name="dept" type="xs:integer"/>
<!-- attributes -->
<xs:attribute name="id" type="xs:integer"/>
<!-- complex elements -->
<xs:element name="department">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="hod" minOccurs="0"/>
</xs:sequence>
<xs:attribute ref="id" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="departments">
<xs:complexType>
<xs:sequence>
<xs:element ref="department" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="student">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="dept"/>
</xs:sequence>
<xs:attribute ref="id" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element ref="student" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="school">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="departments"/>
<xs:element ref="students"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
As per the schema, the attribute id is required for <department> and <student> tags and I have below XML which adheres to this rule
<?xml version="1.0" encoding="UTF-8"?>
<school xmlns="http://www.learnjava.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.learnjava.com ex2.xsd">
<name>TAMUC</name>
<departments>
<department id="1001">
<name>Computer Science</name>
</department>
<department id="1002">
<name>Social Science</name>
<hod>Jeff</hod>
</department>
</departments>
<students>
<student id="5001">
<name>Frank</name>
<dept>1001</dept>
</student>
<student id="5002">
<name>Paul</name>
<dept>1001</dept>
</student>
</students>
</school>
But the validation fails with below error
Error - Line 7, 25: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 25; cvc-complex-type.3.2.2: Attribute 'id' is not allowed to appear in element 'department'.
Error - Line 7, 25: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 25; cvc-complex-type.4: Attribute 'id' must appear on element 'department'.
[..further errors omited...]
Not sure for what is wrong. Both the error messages are contradictory
The validation fails if I remove "id" attributes from and as well as when I have it
I have a work around to make this work, by modifying the XSD like the one below
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified">
<xs:element name="school">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="departments">
<xs:complexType>
<xs:sequence>
<xs:element name="department" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="hod" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element name="student" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="dept" type="xs:integer"/>
</xs:sequence>
<xs:attribute name="id" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
but as an XML novice, I am curious to know what is wrong in the earlier XSD
PS:
1. I'm using http://www.utilities-online.info/xsdvalidation/#.VYpP8vmqqko to validate XML against the XSD.
2. I observe the same error in Altova XML Spy editor as well.
the problem is that the attribute id has been declared global(direct child of xs:schema). therefore, the attribute id should be qualified with the namespaces http://www.learnjava.com. Notice that id is not the same thing as http://www.learnjava.com:id
If you don't want that the attribute id belong to the namespace:
you should use a local attribute declaration
In your schema document, change
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified"
attributeFormDefault="qualified">
to
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.learnjava.com"
xmlns="http://www.learnjava.com"
elementFormDefault="qualified"
>
Update:
If you want to use global attribute declaration, then your xml instance document would look like the following:
<p:school xmlns:p="http://www.learnjava.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.learnjava.com ex2.xsd">
<p:name>TAMUC</p:name>
<p:departments>
<p:department p:id="1001">
<p:name>Computer Science</p:name>
</p:department>
<p:department p:id="1002">
<p:name>Social Science</p:name>
<p:hod>Jeff</p:hod>
</p:department>
</p:departments>
<p:students>
<p:student p:id="5001">
<p:name>Frank</p:name>
<p:dept>1001</p:dept>
</p:student>
<p:student p:id="5002">
<p:name>Paul</p:name>
<p:dept>1001</p:dept>
</p:student>
</p:students>
</p:school>
I want to create an XML schema that contains
<root>
<login>
<username> </username>
<paswword> </paswword>
</login>
</root>
How can i read this values and use them for authentication, with or without JAXB.
Here is the XML schema of your document:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="paswword" type="xs:string"/>
<xs:element name="username" type="xs:string"/>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="login"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="login">
<xs:complexType>
<xs:sequence>
<xs:element ref="username"/>
<xs:element ref="paswword"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Give that schema to some king of script that you are using to generate JAXB objects, pack them into a jar, put it into your classpath and use for your any purposes.
I have this XSD file:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/dnavigator"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:dn="http://www.example.com/dnavigator"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings enableJavaNamingConventions="true"/>
</xs:appinfo>
</xs:annotation>
<xs:element name="DynamicNavigators">
<xs:complexType>
<xs:sequence>
<xs:element name="DynamicNavigator"
type="dn:DynamicNavigator"
minOccurs="1"
maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
</xs:documentation>
<xs:appinfo>
<jaxb:property name="DynamicNavigators"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="DynamicNavigator">
<xs:sequence minOccurs="0"
maxOccurs="unbounded">
<xs:element name="example"
type="xs:string"
minOccurs="1"
maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
I want that the class DynamicNavigator that will be generated, extends the class com.example.MyClass
How can I do it?
Thank you.
JAXB only creates objects for complexTypes, so don't wrap your complexTypes in 'xs:element' tags. Try using 'xs:element ref' within the complexType instead of creating new elements within your complexType. for instance:
<xs:complexType name="DynamicNavigatorsType">
<xs:sequence>
<xs:element ref="dn:DynamicNavigator" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="DynamicNavigatorType">
<xs:sequence>
<xs:element ref="dn:example"/>
</xs:sequence>
</xs:complexType>
<xs:element name="DynamicNavigator" type="dn:DynamicNavigatorType"/>
<xs:element name="example" type="xs:string"/>