My requirement is that any Xml file that will be validated against my schema should conform to following condition.
The OTHERWISE element can contain only CDATA section and nothing else.
Example
Valid XML: <OTHERWISE ContentURI=""><![CDATA[<html>Good-bye</html>]]></OTHERWISE>
Invalid XML: <OTHERWISE ContentURI="">ABC</OTHERWISE>
I am trying the following:
<xs:simpleContent>
<xs:restriction base="OtherwiseAtt">
<xs:pattern value="^<\!\[CDATA\[[a-zA-Z0-9]*\]\]>" />
</xs:restriction>
</xs:simpleContent>
Any thing can go inside the CDATA. I have put [a-zA-Z0-9]* just for testing purpose.
Please help me out.
Thanks
Sabri
The content between <![CDATA[ and ]]> is handled by the parser. Your XML file has been fully parsed by the time that it is validated. CDATA is basically another way to escape special characters. The validator will not have a way to determine if an element contains CDATA or not in the way that you wish.
The purpose of validation is to place controls on the structure of your documents. It is not and cannot enforce a particular method of escaping text.
Why would you need to require that the content is escaped by CDATA? This sounds like an attempt to handle a poor design choice at an earlier stage.
Related
How can I guarantee that the url element starts with "http://"?
<xs:element name="url" type="xs:anyURI"/>
You can add a xs:restriction for a Regular Expression using xs:pattern:
<xs:element name="url">
<xs:simpleType>
<xs:restriction base="xs:anyURI">
<xs:pattern value="http://.+" />
</xs:restriction>
</xs:simpleType>
</xs:element>
This will match to anything that starts with http://. It will match:
http://www.stackoverflow.com
http://somethingsomethingsomething
http://123456789!!!!!
http://0
It will not match https URLs:
https://github.com
If you want to match https as well you can change the pattern to
https?://.+
which means that the s is allowed and is optional.
If you want to match only valid URLs then you need to improve it to check for characters, followed by a dot, more characters, a valid domain suffix, etc. If you search for URL validation via regex you will find several examples. You can also try this resource. And to experiment with Regex, Regex 101 is a great resource.
Pattern matching in XSD has some restrictions. Check this SO question/answer which discusses that.
I got the following complex type within my XSD schema
<xs:complexType name="structure" mixed="true">
<xs:choice maxOccurs="unbounded">
<xs:element type="b" name="b" />
<xs:element type="a" name="a" />
</xs:choice>
</xs:complexType>
which allows me to state XML definitions like this:
<structure>
Hello <b>World</b>
Hello 2 <b>World 2</b>
<a>Hello3</a> <b>World3</b>
</structure>
Now I tried to generate XSD classes out of my schema, I tried both XSD.exe as well as XSD2Code. They both generate something like
class structure {
List<a> a;
List<b> b;
List<string> text;
}
My problem is, that I need to keep track in which order those elements where defined within the XML content of structure. Refering to the above example, I would like to know that the inner text "Hello" comes right before the first occurance of the b-element.
As this would obviously require a more specialized generator strategy, maybe I'm expecting too much, but: is there any XSD generator that can handle the object order or do I have to write my own classes?
Thank you in advance
I have never seen an XSD to code binding tool which would do what you need here, for sure not on the .NET platform - which you seem to imply as the target. This is one of those cases where roundtrip an XML is not possible, without loss of fidelity (deserialize, serialize then compare, it fails). Just for completeness, the /order option wouldn't work with xsd.exe, simply because in terms of the XSD you defined, there's no order really. It is, also, a limitation of what XSD can describe, which inevitably is reflected in tool implementations.
I'm trying to validate a really simple xml using xsd, but for some reason I get this error.
I'll really appreciate if someone can explain me why.
XML File
<?xml version="1.0" encoding="utf-8"?>
<MyElement>A</MyElement>
XSD File
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/Test"
xmlns:tns="http://www.example.org/Test"
elementFormDefault="qualified">
<simpleType name="MyType">
<restriction base="string"></restriction>
</simpleType>
<element name="MyElement" type="tns:MyType"></element>
</schema>
Your schema is for its target namespace http://www.example.org/Test so it defines an element with name MyElement in that target namespace http://www.example.org/Test. Your instance document however has an element with name MyElement in no namespace. That is why the validating parser tells you it can't find a declaration for that element, you haven't provided a schema for elements in no namespace.
You either need to change the schema to not use a target namespace at all or you need to change the instance to use e.g. <MyElement xmlns="http://www.example.org/Test">A</MyElement>.
After making the change suggested above by Martin, I was still getting the same error. I had to make an additional change to my parsing code. I was parsing the XML file via a DocumentBuilder as shown in the oracle docs:
https://docs.oracle.com/javase/7/docs/api/javax/xml/validation/package-summary.html
// parse an XML document into a DOM tree
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = parser.parse(new File("example.xml"));
The problem was that DocumentBuilder is not namespace aware by default. The following additional change resolved the issue:
// parse an XML document into a DOM tree
DocumentBuilderFactory dmfactory = DocumentBuilderFactory.newInstance();
dmfactory.setNamespaceAware(true);
DocumentBuilder parser = dmfactory.newDocumentBuilder();
Document document = parser.parse(new File("example.xml"));
I had this error for my XXX element and it was because my XSD was wrongly formatted according to javax.xml.bind v2.2.11 . I think it's using an older XSD format but I didn't bother to confirm.
My initial wrong XSD was alike the following:
<xs:element name="Document" type="Document"/>
...
<xs:complexType name="Document">
<xs:sequence>
<xs:element name="XXX" type="XXX_TYPE"/>
</xs:sequence>
</xs:complexType>
The good XSD format for my migration to succeed was the following:
<xs:element name="Document">
<xs:complexType>
<xs:sequence>
<xs:element ref="XXX"/>
</xs:sequence>
</xs:complexType>
</xs:element>
...
<xs:element name="XXX" type="XXX_TYPE"/>
And so on for every similar XSD nodes.
I got this same error working in Eclipse with Maven with the additional information
schema_reference.4: Failed to read schema document 'https://maven.apache.org/xsd/maven-4.0.0.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
This was after copying in a new controller and it's interface from a Thymeleaf example. Honestly, no matter how careful I am I still am at a loss to understand how one is expected to figure this out. On a (lucky) guess I right clicked the project, clicked Maven and Update Project which cleared up the issue.
To expand upon the top answer. If you're using Java Web Services (JAX-WS) annotations to define your services, like in this example:
#WebService(..., targetNamespace = "http://bar.foo.com/")
Then make sure that your SOAP request has exactly the same namespace as defined in your annotation:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:foo="http://bar.foo.com/">
<soapenv:Header/>
<soapenv:Body>
<foo:someRequest>
...
</foo:someRequest>
</soapenv:Body>
</soapenv:Envelope>
The targetNamespace in your annotation and the xmlns:foo property in the XML request must match! Literally every character (including whitespace) must match. Also don't forget to put the / at the end as well (it's a very common mistake).
Although the XML file being described by the XSD Schema may contain any unicode characters in general, there are some fields where only ASCII is allowed. (As these strings are going to be passed to another system which only accepts ASCII.)
Is there a way to specify that in XSD?
A regexp with all possible ASCII characters would be a possibility I suppose, but I feel there must be a better way.
You can try that :
<xs:simpleType name="basicLatin">
<xs:restriction base="xs:string">
<xs:pattern value="\p{IsBasicLatin}*"/>
</xs:restriction>
</xs:simpleType>
Unfortunately, for your requirement there isn't a way to restrict without using patterns.
restrict special characters in my XSD validation , i am able to handle , some characters with this pattern "([a-zA-Z0-9_.' !##$%^*()_+={}|/:;,>?/`~ ])+"
but not able to handle below :
"
&
'
<
\
®
™
any ideas ?
also not able to handle them with [^] pattern
You want define a type that extends string and add a restriction with a pattern
Something like
<xs:element name="your_element">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9_.' !##$%^*()_+={}|/:;,>?/`~ ]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Or you can add the escape character \ (backslash) before any special character you want to add to the pattern. For example:
<xs:pattern value="[a-zA-Z 0-9_.,()/=!\[\]"#%&*;<>'+:?-]"/>
where you see the square brackets [ and ] included in the pattern.
I think you need to use character entities. & for the ampersand, for example, and < for the less. XML Schema is XML, and you have to live with XML rules. Expanding your question to actually show us the schema context would help.