I've made a mistake but I can't see what it is...
I'm trying to validate a piece of XML (a SOAP message) using Java, against an XSD. It's failing on what I think should be a valid piece of XML/message with the Exception:
org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'tns:Envelope'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203).
Note 1: I've debugged xmlSource and xsdSource and they contain the expected Readers with the expected Strings.
Note 2: The content of the XML cannot be changed. I am a consumer only.
Note 3: As the XML is a SOAP message I grabbed the XSD from the Web. This therefore could be incorrect.
Note 4: I've simplified the incoming message for brevity but get the same error with the "actual" message.
Java
#Override
public boolean isMessageValid(final String xml) {
try {
final Source xmlSource = getStreamSource(xml);
final Source xsdSource = getStreamSource(fileService.getResourceFileAsString("xsd/soap-envelope.xsd"));
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final Schema schema = schemaFactory.newSchema(xsdSource);
final Validator validator = schema.newValidator();
validator.validate(xmlSource);
return true;
} catch (final Exception ex) {
LOG.error("Exception whilst validating message", ex);
return false;
}
}
private StreamSource getStreamSource(final String xml) {
return new StreamSource(new StringReader(xml));
}
XML
<?xml version="1.0" encoding="UTF-8"?>
<tns:Envelope xsi:schemaLocation="http://www.w3.org/2001/12/soap-envelope soap-envelope.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.w3.org/2001/12/soap-envelope">
<tns:Body>
<!-- snipped -->
<someThing>else</someThing>
</tns:Body>
</tns:Envelope>
XSD
<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/"
targetNamespace="http://schemas.xmlsoap.org/soap/envelope/" >
<!-- Envelope, header and body -->
<xs:element name="Envelope" type="tns:Envelope" />
<xs:complexType name="Envelope" >
<xs:sequence>
<xs:element ref="tns:Header" minOccurs="0" />
<xs:element ref="tns:Body" minOccurs="1" />
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Header" type="tns:Header" />
<xs:complexType name="Header" >
<xs:sequence>
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Body" type="tns:Body" />
<xs:complexType name="Body" >
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" >
<xs:annotation>
<xs:documentation>
Prose in the spec does not specify that attributes are allowed on the Body element
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
<!-- Global Attributes. The following attributes are intended to be usable via qualified attribute names on any complex type referencing them. -->
<xs:attribute name="mustUnderstand" >
<xs:simpleType>
<xs:restriction base='xs:boolean'>
<xs:pattern value='0|1' />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="actor" type="xs:anyURI" />
<xs:simpleType name="encodingStyle" >
<xs:annotation>
<xs:documentation>
'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification
</xs:documentation>
</xs:annotation>
<xs:list itemType="xs:anyURI" />
</xs:simpleType>
<xs:attribute name="encodingStyle" type="tns:encodingStyle" />
<xs:attributeGroup name="encodingStyle" >
<xs:attribute ref="tns:encodingStyle" />
</xs:attributeGroup>
<xs:element name="Fault" type="tns:Fault" />
<xs:complexType name="Fault" final="extension" >
<xs:annotation>
<xs:documentation>
Fault reporting structure
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="faultcode" type="xs:QName" />
<xs:element name="faultstring" type="xs:string" />
<xs:element name="faultactor" type="xs:anyURI" minOccurs="0" />
<xs:element name="detail" type="tns:detail" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="detail">
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" />
</xs:complexType>
</xs:schema>
I reckon I've done something noddy.
Thanks in advance
The prefix "tns" is bound to different namespaces in the source and in the schema. So this is not a schema for the vocabulary of your source document.
Related
I'm creating a Spring based SOAP web service, and I'm trying to return a custom list called AVAILABLE_PACKAGES which contains multiple PACKAGE_ITEM elements. Each one of these PACKAGE_ITEM elements is made by two strings, PACKAGE_NAME and PACKAGE_PRICE.
I tried with multiple configurations, but I keep receiving an error on the line
<xs:element name="availablePackagesList" type="xs:AvailablePackagesList" />
The error reads as follows:
Multiple annotations found at this line:
src-resolve: Cannot resolve the name 'xs:AvailablePackagesList' to a(n) 'type definition' component.
src-resolve.4.2: Error resolving component 'xs:AvailablePackagesList'. It was detected that
'xs:AvailablePackagesList' is in namespace
'http://www.w3.org/2001/XMLSchema', but components from this
namespace are not referenceable from schema document...
This is the code snippet of what I have on my .xsd file
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http:/hello.com/queries"
xmlns:tns="http:/hello.com/queries"
elementFormDefault="qualified">
<!--GetSubscriberAvailablePackages -->
<xs:element
name="MobileGetSubscriberAvailablePackagesRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="network" type="xs:string" />
<xs:element name="username" type="xs:string" />
<xs:element name="password" type="xs:string" />
<xs:element name="subscriberData" type="xs:string" />
<xs:element name="subscriberDataType" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element
name="MobileGetSubscriberAvailablePackagesResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="network" type="xs:string" />
<xs:element name="subscriberData" type="xs:string" />
<xs:element name="subscriberDataType" type="xs:string" />
<xs:element name="response" type="xs:string" />
<xs:element name="responseDetails" type="xs:string" />
<xs:element name="availablePackagesList"
type="xs:AvailablePackagesList" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="AvailablePackagesList">
<xs:sequence>
<xs:element name="AvaillablePackage"
type="xs:AvaillablePackageItem" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AvaillablePackageItem">
<xs:attribute name="packageName" type="xs:integer"
use="required" />
<xs:attribute name="packagePrice" type="xs:integer"
use="required" />
</xs:complexType>
To eliminate your immediate error and one subsequent error,
change type="xs:AvailablePackagesList" to type="tns:AvailablePackagesList", and
changetype="xs:AvaillablePackageItem" to type="tns:AvaillablePackageItem"
because both are in the http:/yobitelecom.com/queries namespace, not the http://www.w3.org/2001/XMLSchema namespace.
I have a complex XML Structure as below which needs to be unmarshalled:
<abc>
<pqr>
<attribute>name</attribute>
<entry>
<priorityKey>
<class>123</class>
<reason>abc</reason>
</prioritykey>
<priority> 1 </priority>
</entry>
<entry>
<prioritykey>
<class>456</class>
<reason>abc1</reason>
</prioritykey>
<priority>2</priority>
</entry>
</pqr>
<pqr>
'''
'''
</pqr>
</abc>
abc is the root node. It can have multiple pqr elements. Each pqr element has one attribute node and multiple entry nodes. So I believe it will be of type HashMap(entry,attribute).
Each entry in turn has prioritykey and priority which I believe will be of type HashMap (prioritykey,priority).
Need to unmarshall this xml but not getting how to configure the XMLAdapter
Here, create the contract first. I created one as part of my learning process...
<xs:element name="abc" type="abcType" />
<xs:complexType name="abcType">
<xs:sequence>
<xs:element name="pqr" type="pqrType" minOccurs="1"
maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="pqrType">
<xs:sequence>
<xs:element name="attribute" type="xs:string" minOccurs="1"
maxOccurs="1" />
<xs:element name="entry" type="entryType" minOccurs="1"
maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="entryType" >
<xs:sequence>
<xs:element name="priorityKey" type="priorityKeyType"
minOccurs="1" maxOccurs="1" />
<xs:element name="priority" type="xs:int" minOccurs="1"
maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="priorityKeyType">
<xs:sequence>
<xs:element name="class" type="xs:int" minOccurs="1"
maxOccurs="1" />
<xs:element name="reason" type="xs:string" minOccurs="1"
maxOccurs="1" />
</xs:sequence>
</xs:complexType>
Copy and save this in an fileName.xsd file.
Now, generate JAXB classes or artifacts. If you are using an IDE, then this is simple. Click on the fileName.xsd file and you should get some option to generate JAXB artifacts. Otherwise, you can always use jaxb-xjc.jar present in the lib present in the JAXB download.
Command for the same - java -jar jaxb-xjc.jar fileName.xsd.
As the artifacts are in place, you can use them to unmarshall the xml content in question.
My transaction xml is shown below
<?xml version= "1.0"?>
<transactionlist>
<transaction action="c">
<transactionid>t004</transactionid>
<transactiondate>11/06/2013</transactiondate>
<merchantdetails>Sony wholesale Dealer</merchantdetails>
<itempurchased>3</itempurchased>
<amount>40399</amount>
<description>sony laptops</description>
</transaction>
<transaction action="d">
<transactionid>t003</transactionid>
</transaction>
<transaction action="u">
<transactionid>T001</transactionid>
<transactiondate>20/08/2013</transactiondate>
<merchantdetails>samsung Axses</merchantdetails>
<itempurchased>1</itempurchased>
<amount>40000</amount>
<description>samsung smart phone</description>
</transaction>
</transactionlist>
I have parsed the element itempurchased in above xml and stored it in integer variable. How to validate itempurchased only for numbers. that is i want to check whether itempurchased is number. pls provide suggestions
the best way should be validate xml against an xsd, where itempurchased would be of type xsd:int
below the xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="transactionlist">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="transaction">
<xs:complexType>
<xs:sequence>
<xs:element name="transactionid" type="xs:string" />
<xs:element minOccurs="0" name="transactiondate" type="xs:string" />
<xs:element minOccurs="0" name="merchantdetails" type="xs:string" />
<xs:element minOccurs="0" name="itempurchased" type="xs:int" />
<xs:element minOccurs="0" name="amount" type="xs:int" />
<xs:element minOccurs="0" name="description" type="xs:string" />
</xs:sequence>
<xs:attribute name="action" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Here Validating XML against XSD the code for validate xml against xsd
If you are marshaling your xml to a java bean then you may try using the Java6 Bean Validation Framework. Read more about it here:
http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html
It is as simple as putting an annotation on your bean:
public class MyXMLBean {
#Max(10)
#Min(5)
private int itempurchased;
}
The above bean will allow setting the value of itempurchased between min and max values mentioned in the annotations.
I have the following XML file:
<?xml version="1.0"?>
<!DOCTYPE library SYSTEM "library.dtd">
<library
xmlns="http://example.com/a"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.com library.xsd"
name=".NET Developer's Library">
<book>
<category>computerss</category>
<title>Programming Microsoft .NET</title>
<author>Jeff Prosise</author>
<isbn>0-7356-1376-1</isbn>
</book>
<book>
<category>computer</category>
<title>Microsoft .NET for Programmers</title>
<author>Fergal Grimes</author>
<isbn>1-930110-19-7</isbn>
</book>
</library>
And the following Java code:
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
SchemaFactory sf = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
docBuilderFactory.setSchema(sf.newSchema(new File("library.xsd")));
docBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
docBuilder.parse(new FileInputStream("data.xml"));
It produces the following error:
[Error] :7:33: cvc-elt.1: Cannot find the declaration of element 'library'.
If I remove the XSD declaration in the XML file everything works fine...
Any inside highly appreciated. Thanks.
And here is the schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="library">
<xs:complexType>
<xs:sequence>
<xs:element ref="book" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element ref="category"/>
<xs:element ref="title"/>
<xs:element ref="author"/>
<xs:element ref="isbn"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="category">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="computer" />
<xs:enumeration value="poetry" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
<xs:element name="isbn" type="xs:string"/>
</xs:schema>
Your XML has a reference to namespace (xmlns="http://example.com/a") which is not the same as in your schema. Have you tried to validate your XML against schema in any XML editor (e.g. Altova or Eclipse etc).
So far it looks like your parsing error is legit, XML is not valid according to the schema.
Your schema definition is incorrect. For a start, as maximdim says, your schema has no targetNamespace="http://mysite.com/a" attribute in the schema tag.
Secondly your schema looks as if it should only have a single root element, yours has 6.
A correct schema for your XML instance would be:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://mysite.com/a" targetNamespace="http://mysite.com/a">
<xs:element name="library">
<xs:complexType>
<xs:sequence>
<xs:element name="book" type="book" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="book">
<xs:sequence>
<xs:element name="category">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="computer" />
<xs:enumeration value="poetry" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
<xs:element name="isbn" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
I make xml file using Jaxb from a xml schema my existing xml file looks like
<transaction>
<id>
<in>computer</in>
<sn>1234567</sn>
<book>JAVA</book>
<author>klen</author>
</id>
<data>
<dateTime>2011-06-24T17:08:36.3727674+05:30</dateTime>
<key>Err</key>
</data>
</transaction>
but I want to add inline schema before <id> node
My schema is looking like
<xs:schema id="transaction" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="transaction" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="id">
<xs:complexType>
<xs:sequence>
<xs:element name="in" type="xs:string" minOccurs="0" />
<xs:element name="sn" type="xs:string" minOccurs="0" />
<xs:element name="book" type="xs:string" minOccurs="0" />
<xs:element name="author" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="dateTime" type="xs:dateTime" minOccurs="0" />
<xs:element name="key" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="productData">
<xs:complexType>
<xs:sequence>
<xs:element name="dateTime" type="xs:dateTime" minOccurs="0" />
<xs:element name="key" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
now I want to add this before node under node.
Is it possible using Jaxb in first time?I cannot generate xml file with inline schema using jaxb.Due to the large size of my xml I cannot do this using Dom parser.Presently I try that at first generate xml file with data using jaxb and then rewrite the xml file and add schema under <transaction> node before <id> node.
I will prefer sun provided api.I am new in java so if some codesnips will be added it will be help full for me.