I‘m having trouble to understand, what the length restriction means to strings in XML schema language. I tested two different XMLSchema validator implementations and got inconsistent results. I used the following schema and file for testing:
<?xml version="1.0" encoding="UTF-8"?>
<test xmlns="http://www.example.org/NewXMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/NewXMLSchema NewXMLSchema.xsd ">
<id>😀xx</id>
</test>
and
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/NewXMLSchema" xmlns:tns="http://www.example.org/NewXMLSchema" elementFormDefault="qualified">
<simpleType name="MyFixedString">
<restriction base="string">
<maxLength value="3"></maxLength>
</restriction>
</simpleType>
<complexType name="NewComplexType">
<sequence>
<element name="id" type="tns:MyFixedString"></element>
</sequence>
</complexType>
<element name="test" type="tns:NewComplexType"></element>
</schema>
The IDE pycharm gives an error in underlining the id element with a read line, that it isn‘t schema compliant. The python code executed with Python 3 says the XML file is schema compliant.
I wonder if the XML file s schema-compliant or not. I think the point is, how chars (whatever that term exactly means) are counted: The length of a string is the number of unicode codepoints or the number of utf16 surrogates or the number of graphemes.
Is it possible, that the implementation (Python 3, which used AFAIK UFT-32) and Java (UTF-16) leaks into the XMLSchema validation?
Any suggestings?
-- Mik
BTW: The Java 8 builtin schema processor complains my example is not schema compliant, too.
The correct semantics of maxLength is that it applies to the number of Unicode characters (codepoints) and not to the number of octets (or 16-bit code units) in any particular encoding of the string.
Whether all schema validators out there actually conform to this definition, I cannot say. But the definition is clear.
Your sample validates fine using the Saxon schema validator, by the way.
Related
I have the following XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:x="MY_NAMESPACE"
targetNamespace="MY_NAMESPACE">
<xs:element name="response" type="x:responseType"/>
<xs:complexType name="responseType">
<xs:all>
<xs:element name="param" type="x:responseParam"/>
</xs:all>
</xs:complexType>
<xs:complexType name="responseParam">
<xs:all>
<xs:element name="value" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:schema>
I use it to generate JAXB classes for unmarshalling a payload like the following:
<x:response xmlns:x="MY_NAMESPACE">
<param>
<value>OK</value>
</param>
</x:response>
via getWebServiceTemplate().marshalSendAndReceive in Spring. Problem is, I also want to unmarshal payloads without the namespace prefix, like this:
<response xmlns="MY_NAMESPACE">
<param>
<value>OK</value>
</param>
</response>
In this case, the response tag is parsed correctly, but the object reference representing param is always null. How can I edit my XSD to make things work? I already tried setting elementFormDefault="qualified" in the schema, or even form="qualified" on the param element.
Additional info that comes to mind (I might edit and add more depending on comments):
The unmarshaller is a Jaxb2Marshaller.
The XML documents
I think you probably know this, but removing that namespace prefix affects the entire document (because the 'param' and 'value' tags do not have any prefix and therefore inherit the default namespace binding). Becauses of this, in the first document the root tag 'response' is in namespace 'MY_NAMESPACE' and the other tags do not have any namespace. In the second document, all of the tags are in namespace 'MY_NAMESPACE'.
The XML Schema
The elementFormDefault attribute defaults to 'unqualified' so your schema should match the first document and reject the second. Your experiments confirm this.
If you set elementFormDefault to 'qualified' then it will reject the first document and match the second one.
There is no value of elementFormDefault that will make the XSD match both XML documents. The namespace is an integral part of the identity of the element.
Possible solution
If you are determined to construct an XSD that matches both documents then it could be done as follows:
explicitly set elementFormDefault to 'unqualified' (optional, but you're about to rely on that setting)b
wrap the current (globally-declared) contents of responseType in a choice group
add a second branch in the choice group containing a local declaration of element 'param' and all of its descendants. Because those are locally declared, they will be in noTargetNamespace.
This is not a general solution to the problem of making JAXB ignore namespaces, and I don't think you will find one (although I'm happy to be corrected by somebody who knows more than I do about JAXB).
Having said all of the above...I think you are probably solving the wrong problem. The JAXB standard is based on XML Schema. An XSD is not meant to tolerate the wrong namespaces. The second XML document is therefore invalid, and should be corrected by whoever is generating it.
Small question about JAXB auto code generation.
For the comment part, it will generate some schema like following:
<element name="partner_system_priority" type="{http://www.w3.org/2001/XMLSchema}int"/>
I want to know why JAXB dont make > as a >?
Br,
Tim
This comment is generated for javadoc tool.
So this comment will be a part of HTML page after javadoc generation.
It is enough to replace only first less then (<) symbol with < in HTML report.
Both
<element name="partner_system_priority"
type="{http://www.w3.org/2001/XMLSchema}int"/>
and
<element name="partner_system_priority"
type="{http://www.w3.org/2001/XMLSchema}int"/>
will be interpreted by browser as
<element name="partner_system_priority"
type="{http://www.w3.org/2001/XMLSchema}int"/>
So, no reason to do redundant replacement
This is xsd file
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/onetext"
xmlns:tns="http://www.example.org/onetext"
elementFormDefault="qualified">
<element name="edge">
<complexType>
<attribute name="x" type="float"></attribute>
<attribute name="y" type="float"></attribute>
<attribute name="height" type="float"></attribute>
<attribute name="width" type="float"></attribute>
<attribute name="xhref" type="string"></attribute>
<attribute name="id" type="string"></attribute>
<attribute name="isLocked" type="string"></attribute>
<attribute name="rx" type="double"></attribute>
<attribute name="ry" type="float"></attribute>
<attribute name="rotation" type="float"></attribute>
</complexType>
</element>
</schema>
This is xml file ,
<?xml version="1.0" encoding="UTF-8"?>
<edge xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.example.org/onetext"
xmlns:web="http://www.example.org/onetext"
xsi:schemaLocation="web_one/WebContent onetext.xsd"
id="WebApp_ID" version="3.0">
<image x="336"
y="52"
height="57.6"
width="57.6"
xhref="/dccp_repository/dam/logo/images/accc_logo.jpg"
id="Image_3"
isLocked="false"
rx="336"
ry="52"
rotation="0" />
</edge>
I faced this kind of problem.
No grammar constraints (DTD or XML schema) detected for the document.
in xml document.
If I changed root node of xml file like given below
<edge xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:web="web_one/WebContent/onetext.xsd"
xsi:schemaLocation="web_one/WebContent
web_one/WebContent/onetext.xsd"
id="WebApp_ID"
version="3.0">
then I faced this kind of error
cvc-elt.1: Cannot find the declaration of element 'edge'.
I confused with this concept. Please help.
The schema document you show declares an element named edge in the namespace http://www.example.org/onetext (the value of the targetNamespace attribute on the schema element). So far, so good.
In your first XML document instance, the outermost element is named edge, and it is in the namespace http://www.example.org/onetext. That's consistent with the declaration in the schema document. So far, so good. If you invoke an XSD validator telling it to use your schema document to find declarations for elements in the http://www.example.com/onetext namespace, all should be well and the validator should be able to validate your document. When it does, it will tell you that edge elements are declared as having no children, so the edge element in the document instance is not valid, because it has a child named image (in the namespace http://www.example.org/onetext). The validator may also mention that the schema has no declaration for any element named image in that namespace. When you get these error messages, your current problem will be solved and you can get on to the next problem of making your schema and your XML agree on the data format you are defining and using.
But at the moment, that is not happening. Why not? In your first XML instance, your outermost element has xsi:schemaLocation="web_one/WebContent onetext.xsd". Translated into English, this means "Hello, schema validator. If you are looking for schema declarations for elements in the namespace web_one/WebContent, you will find a schema document for that namespace at the location onetext.xsd. Have a nice day!" (Well, the spec doesn't actually say anything about having a nice day; that's just my interpretation.) There are a few things wrong with this:
The string web_one/WebContent is not an absolute URI, so it is not appropriate as a namespace name.
The elements in the document instance both are in namespace http://www.example.org/onetext, and your xsi:schemaLocation attribute tells the schema validator nothing about where to find declarations for that namespace.
If the validator actually reads the schema document onetext.xsd, and if that is the schema document you are showing us, then the validator ought to complain that the namespace name web_one/WebContent does not match the target namespace of the schema document.
The error message you're getting (No grammar constraints ... detected for the document) reflects point 2: your validator is not finding any declarations for the only namespace relevant to your instance document.
The way to correct this is to replace your current xsi:schemaLocation attribute value specification with something like xsi:schemaLocation = "http://www.example.org/onetext onetext.xsd" (assuming that the document onetext.xsd is the schema document you show us, and that it's in the same directory as the document instance being validated -- otherwise, use a correctly formulated relative URI).
Your second XML instance document contains an edge document in namespace http://www.w3.org/2001/XMLSchema. The validator doesn't need a pointer to a schema document for this namespace: it's the XSD namespace, and XSD validators typically have the schema for that namespace hard-coded into them. So its error message is not about not finding any schema; instead, the error message is about not finding a declaration for any element named edge in the XSD namespace.
The change made in the second XML instance can seem plausible only to someone who does not really understand XML namespaces or XML namespace declarations. So it allows me to suggest that what you really need to do is spend an hour or two learning how namespaces work in XML and how a parser understands from your document what (namespace-name, local-name) pair to associate with each element and attribute. Once you do that, many things relating to XSD schemas (in particular, many error messages) will be somewhat less mysterious.
Good luck!
This is how XML look
<element>
<complextype name="edge">
<height>some words here</height>
<width>some words here</width>
</complextype>
</element>
Tips: the <element> is the root and does not need a. name.
<complextype> is the one u can add name to which is the Child.
The <height> does not need much styling except you want to use DTD for your styling
I have an XSD that defines a complexType (say 'FooType'), and several named instances of this type scattered throughout the same XSD, like:
<sequence>
<element name="A" type="tns:FooType"/>
<element name="B" type="tns:FooType"/>
</sequence>
When working with an XML file derived from the XSD, I want to find all element nodes that of the type "tns:FooType". I think this is possible using XPath with the element(*, "FooType) method, but I can't find any examples of this so don't know what the syntax would look like. I'm hoping to use this with the Java dom4j selectNodes() method.
You need an XPath 2.0 implementation. DOM4J is 1.0 only, and so is javax.xml.xpath. Saxon provides 2.0, but I believe this specific capability is not part of the open source edition.
Try this:
List list = document.selectNodes( "/sequence/element[#type='tns:FooType']" );
If you do not know the prefix you could use substring-before() on the name and check if there is a result:
/sequence/element[substring-before(#type,":FooType")]
I have two schemas which are processed using JAXB. The first schema is preprocessed and information of this is used using an episode file (following http://www.java.net/blog/2006/09/05/separate-compilation-jaxb-ri-21).
The second schema imports the first, and again using jaxb, is processed. This all works as expected.
But now I have an element in the first schema, which is used in the second using a reference.
Schema a:
<schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:test="http://www.example.org/Test/"
targetNamespace="http://www.example.org/Test/">
<element name="type" type="test:MyType"></element>
Schema b:
<schema elementFormDefault="qualified"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:second="http://www.example.org/Second/"
xmlns:test="http://www.example.org/Test/"
targetNamespace="http://www.example.org/Second/">
<import namespace="http://www.example.org/Test/" />
<complexType name="SomeType">
<sequence>
<element ref="test:type" minOccurs="1" maxOccurs="unbounded" />
</sequence>
</complexType>
During processing nothing is wrong, but the generated code for both schemas provide the same method:
public JAXBElement<EventType> createType(TypeType value)
At runtime, this results in the following error:
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of
IllegalAnnotationExceptions
The element name {http://www.example.org/Type/}type has more than one mapping.
How can I prevent JAXB from creating the duplicate createType methods?
Thanks in advance!
Update: I asked this same question on the JAXB mailing list, on that list I also posted a working example. The thread and example can be found at: http://java.net/projects/jaxb/lists/users/archive/2011-03/message/18
On this list I've been suggested a workaround, and now I can use the schemas the way I like. But I still think JAXB should not create the additional "create" method, since it should already be in the episode file.
I've written a few Schema Definitions in my day. You are declaring your first xsd in your second schema declaration and then you are importing it.
As per MSDN, when you import an XSD you do not include it in the Schema Declaration.
This is where it is in your schema declaration.
xmlns:test="http://www.example.org/Test/"
Remove this and just do the import... ( <xs:import namespace="http://www.example.com/IPO" /> )
see:http://msdn.microsoft.com/en-us/library/ms256480.aspx