Parsing XML schema java - java

I need to parse XML schema (source can be wsdl file or xsd ) and extract all the complex types and their constituent elements with their types.. I have used JAXB (xjc)but it does not return me a list of all complexTypes . Which alternative (XSOM) should I use? I would prefer some built-in library in jdk6.
`
<element name="BankLoanProcessRequest">
<complexType>
<sequence>
<element name="ClientId" type="int"/>
<element name="LoanAmount" type="double"/>
</sequence>
</complexType>
</element>`

you can use JDOM or DOM4j-
here are the link -
http://www.jdom.org/
http://dom4j.sourceforge.net/

Related

Using SAML Assertion in XSD

I have a webservice operation where i'll be getting SAML Assertion as part of the request Body.
I have following XSD:
<xsd:element name="CreateRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="info" type="SomeRequestObj"/>
<xsd:element ref="saml:Assertion" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
The saml:Assertion refers to:
<xsd:import namespace="urn:oasis:names:tc:SAML:2.0:assertion"schemaLocation="../samlv2_0/saml-schema-assertion-2.0.xsd"/>
This saml schema is copied from SAML 2.0.
This generates classes with name *Type.java.
And i am having a hard time creating a unit test for this (which is a separate application with UI).
My Request requires a SAML AssertionType element in the request Body.
So, i cannot use OpneSaml for generating that as it gives me a SAML Assertion object and not AssertionType.
I tried generating the AssertionType object manually but i am having a hard time doing so.
Is there a way to use OpenSaml for generating this?
As i see the xml is going to be the same that i would get in case i just use OpenSaml to generate Assertion object.
Is there a way to simplify this?
EDIT: Added XSD snippet of Assertion
<element name="Assertion" type="saml:AssertionType"/>
<complexType name="AssertionType">
<sequence>
<element ref="saml:Issuer"/>
<element ref="ds:Signature" minOccurs="0"/>
<element ref="saml:Subject" minOccurs="0"/>
<element ref="saml:Conditions" minOccurs="0"/>
<element ref="saml:Advice" minOccurs="0"/>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="saml:Statement"/>
<element ref="saml:AuthnStatement"/>
<element ref="saml:AuthzDecisionStatement"/>
<element ref="saml:AttributeStatement"/>
</choice>
</sequence>
<attribute name="Version" type="string" use="required"/>
<attribute name="ID" type="ID" use="required"/>
<attribute name="IssueInstant" type="dateTime" use="required"/>
</complexType>
This generates AssertionType Object.
SAML Assertions are of complex type "AssertionType", but the element name is "Assertion". The <Assertion> element generated by OpenSaml should be just fine.
The element is defined in section 2.3.3 in the SAML core spec.
Try to use an external binding file when generating the classes from the XSD with JAXB. See this topic (I guess the second answer of it is what you're looking for): JAXB: How to change XJC-generated classes names when attr type is specified in XSD?

Xsd conditional implementation

I am trying to validate a pdf files documentation using xsd, where I convert the given pdf to xml and parse it through the schema xsd, and it validates, but lets assume there is a heading and it has 2 subheadings how do I change to xsd schema such that for a particular type of heading it should and must have minimum 2 subheadings of particular text(words/sentences), how do I add conditions to the xsd file for it validate specifically designed documents ?
here is the xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="elements">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="element"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="element">
<xs:complexType>
<xs:sequence>
<xs:element ref="pageno"/>
</xs:sequence>
<xs:attribute name="level" use="required" type="xs:integer"/>
<xs:attribute name="title" use="required"/>
<xs:attribute name="type" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="pageno" type="xs:integer"/>
</xs:schema>
and here is the xml I used to generate this xsd:
<elements>
<element type ="Introduction" level="1" title="Introduction">
<pageno>4</pageno>
</element>
<element type ="Introduction" level="2" title="Enhancements to the HP CSA vCenter Simple Compute">
<pageno>4</pageno>
</element>
<element type ="System requirements" level="1" title="System requirements">
<pageno>5</pageno>
</element>
<element type ="System requirements" level="2" title="Software components">
<pageno>5</pageno>
</element>
<element type ="Configuration requirements" level="1" title="Configuration requirements">
<pageno>7</pageno>
</element>
<element type ="Configuration requirements" level="2" title="Installing content capsule">
<pageno>7</pageno>
</element>
<element type ="Configuring offerings in HP CSA" level="1" title="Configuring offerings in HP CSA">
<pageno>8</pageno>
</element>
<element type ="Configuring offerings in HP CSA" level="2" title="Configuring subscriber options">
<pageno>8</pageno>
</element>
<element type ="Configuring subscriber options" level="2" title="Adding providers">
<pageno>8</pageno>
</element>
<element type ="Adding providers" level="2" title="Associating resource offerings with providers">
<pageno>9</pageno>
</element>
<element type ="Associating resource offerings with providers" level="2" title="Changing component properties">
<pageno>10</pageno>
</element>
<element type ="Changing component properties" level="2" title="Creating the service offering">
<pageno>12</pageno>
</element>
<element type ="Creating the service offering" level="2" title="Publishing the service offering">
<pageno>13</pageno>
</element>
<element type ="Publishing the service offering" level="3" title="Publishing service offering to a Catalog">
<pageno>13</pageno>
</element>
<element type ="Subscribing to the service" level="1" title="Subscribing to the service">
<pageno>14</pageno>
</element>
<element type ="Subscribing to the service" level="2" title="Canceling a subscription">
<pageno>14</pageno>
</element>
<!-- <element type ="adasdasd" level = "5" title= "dasdsad">
</element> -->
<element type ="Limitations" level="1" title="Limitations">
<pageno>16</pageno>
</element>
<element type ="Appendix A: HP Operations Orchestration flows" level="1" title="Appendix A: HP Operations Orchestration flows">
<pageno>17</pageno>
</element>
<element type ="Appendix B: Integrating with IP Address Management solutions" level="1" title="Appendix B: Integrating with IP Address Management solutions">
<pageno>19</pageno>
</element>
<element type ="Additional resources" level="1" title="Additional resources">
<pageno>20</pageno>
</element>
<element type ="Send Documentation Feedback" level="1" title="Send Documentation Feedback">
<pageno>21</pageno>
</element>
</elements>
If you think I am lacking in clarity in question then please let me know I will answer any queries.
Thank you
You can define a Schema type of your own that is a heading that must contain specific text, and use the conditional type assignment feature of XSD 1.1, if your implementation supports it.
A more widely supported approach is to embed Schematron rules in your schema to do what you want.
Remember that if you over-constrain your input the schema may become fragile -- that is, hard to maintain in the event of changes.

JAXB always marshalls extension - unable to get elements of a super type only

I'm stuck on a problem with JAXB / Spring Web Services. Below is the detailed description. I appreciate any suggestion that could help me to solve it. I can provide more if details if needed.
I am writing a web service that returns list of some entities. Spring WS is contract-first framework, so I started with the XSD similar to:
<element name="GetEntitiesRequest" type="Something"/>
<element name="GetEntitiesResponse" type="Entities"/>
<complexType name="Entities">
<sequence>
<element name="Entity" type="Entity" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="Entity">
<sequence>
(...)
</sequence>
</complexType>
It was working well. However, the "Entity" type begin to grow (there a lot of elements) which caused performance issues (there are many Entities in the response). So I decided to split "Entity" into two parts
Some general information that will be returned within the group response - Entity
More detailed information that will be returned in an another web service operation, specific for the entity - EntityDetails
So after the change the schema is as follows (EntityDetails inherits from Entity):
<element name="GetEntitiesRequest" type="Something"/>
<element name="GetEntitiesResponse" type="Entities"/>
<complexType name="Entities">
<sequence>
<element name="Entity" type="Entity" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="Entity">
<sequence>
(...)
</sequence>
</complexType>
<element name="GetEntityDetailsRequest" type="SomethingMore"/>
<element name="GetEntityDetailsResponse" type="EntityDetails"/>
<complexType name="EntityDetails">
<complexContent>
<extension base="Entity">
<sequence>
(...)
</sequence>
</extension>
</complexContent>
</complexType>
JAXB (precisely: hyperjaxb3) generates classes for Entity (inheritance strategy = JOINED), EntityDetails, and Entities. Also, it creates the ObjectFactory with "createGetEntitiesResponse" method. I am using this method to marshall List retrieved through Hibernate from the Entity table.
Theoretically, I should get list of "Entity" when sending "GetEntitiesRequest". However, I get list of "EntityDetails" instead.
If you read this form the beginning, you can imagine, that this what I wanted to avoid.
If you need more details, persistence.xml is as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence (...)>
<persistence-unit name="org.package">
<class>org.package.Entity</class>
<class>org.package.EntityDetails</class>
<class>org.package.Entities</class>
</persistence-unit>
</persistence>
I use Gradle for the build automation, and its jaxb plugin for the class generation:
jaxb
{
xsdDir = "src/main/webapp/schemas/messages"
bindingsDir = "src/main/webapp/schemas/bindings"
bindings = ["bindings.xjb"]
xjc
{
extension = true
taskClassname = "com.sun.tools.xjc.XJC2Task"
generatePackage = "org.package"
args = ["-Xannotate", "-Xhyperjaxb3-jpa2", "-Xequals", "-XhashCode", "-XtoString"]
}
}
currently, the bindings.xjb, beyond header, contains only:
<jaxb:globalBindings localScoping="toplevel">
<xjc:serializable/>
</jaxb:globalBindings>
First of all, make sure that you get instances Entity from the database, NOT EntityDetails.
Try to create an isolated scenario, without the database. Just instantiate your Entity, fill it with something create the response and marshal it. See what happens.
You'll isolate the problem - either you're getting wrong instances from the database or the marshalling does not work as expected. Both is a bit hard to diagnose without seeing your code. Try to reduce your problem to one of the two I mentioned above.
Diclaimer: I'm the author of Hyperjaxb3.

XSD: constrain attribute value of element to a substring of parent attribute

Consider this piece of XML
<Parent id="MyParent1">
<Child id="MyParent1.MyChild1"/>
</Parent>
<Parent id="MyParent2">
<Child id="MyParent2.MyChild1"/>
<Child id="MySillyIncorrectPrefix.MyChild2"/>
</Parent>
How can I validate (possibly with XSD) Child elements whose id contains the Parent element id as a prefix, so that:
<Child id="MyParent2.MyChild1"/> <!-- is valid -->
<Child id="MySillyIncorrectPrefix.MyChild2"/> <!-- is not valid -->
I'm not bound to XSD version 1.0, so I could try with XSD 1.1 (and features like assertions), but I would like to know:
how to express the above constraint with an xs:assertion or more suitable XSD 1.1
feature.
if it's possible to build a validator in Java leveraging on
that xsd? "Xerces-J" is a feasible solution ?
In my limited knowledge of XSD 1.1 I came up with this attempt:
<xs:element name="Child">
<xs:complexType>
<xs:attribute name="type" type="xs:String" />
<xs:assert test="starts-with(#type,../#type)"/>
</xs:complexType>
</xs:element>
Is this correct? Is there a tool where I could test it?
Being more general: is there a tool to assist the build&test of such XSD 1.1 featured schemas? (afaik Eclipse supports only XSD 1.0)
What you describe is not feasible in XSD 1.0.
In XSD 1.1 you can use assertions on the type of the parent to require each child's id attribute to begin with the value of the parent's id attribute.
This schema should validate the example (use an xsd 1.1 assertion)
<?xml version="1.1" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/stackoverflow" xmlns:tns="http://www.example.org/stackoverflow" elementFormDefault="qualified">
<complexType name="ParentType">
<sequence>
<element name="Child" type="tns:ChildType"
maxOccurs="unbounded" minOccurs="0">
</element>
</sequence>
<attribute name="id" type="string"></attribute>
</complexType>
<element name="Parent" type="tns:ParentType"></element>
<complexType name="ChildType">
<attribute name="id" type="string"></attribute>
<assert test="starts-with(#id,../#id)"/>
</complexType>
</schema>

XMLBeans nested complex element instantiation failure

I'm using XMLBeans to generate java objects from a XSD schema.
The Schema is in the following structure :
<schema targetNamespace="" xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<element name="Father">
<complexType>
<all>
<element name="Son">
<complexType>
<all>
<element name="Target" type="string" />
</all>
</complexType>
</element>
</all>
</complexType>
</element>
</schema>
The schema is compiled allright and I'm able to instantiate the Father by:
Father father = Father.Factory.newInstance();
But when I try to perform :
father.getSon().setTarget("Some String");
I get a null pointer exception. When debugging it, I saw that Son is null (hence the exception).
All I need is to set the "Target" value, but I couldn't figure a way to do it....
Is there a way to auto-build all the XSD structure? Alternatively, can I instantiate the "Son" manually and then access its "Target"?
Thanks a lot!
O.J
getSon() method allows you to get the existing child called Son. If you're trying to generate a new xml, you have to start with an empty document. Then you should add your elements as you wish before accessing them.
Try this code:
FatherDocument fatherDocument = FatherDocument.Factory.newInstance();
Father father = fatherDocument.addNewFather();
Son son = father.addNewSon();
son.setTarget("Some string");
StringWriter writer = new StringWriter();
fatherDocument.save(writer);
System.out.println(writer.toString());
I've generated this xml:
<Father><Son><Target>Some string</Target></Son></Father>

Categories