I have a question regarding the correct usage of the Citrus validation matchers. In the official XML example there is the following XSD schema (TodoList.xsd) defined for a getTodoListResponse:
<xs:element name="getTodoListResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="todoEntry" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="attachment" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="cid" type="xs:string"/>
<xs:element name="contentType" type="xs:string"/>
<xs:element name="data" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="done" type="xs:boolean" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
The validation matcher that is defined looks like this (templates/getTodoListResponse.xml):
<todo:getTodoListResponse xmlns:todo="http://citrusframework.org/samples/todolist">
<todo:list>
<todo:todoEntry>
<todo:id>#ignore#</todo:id>
<todo:title>${todoName}</todo:title>
<todo:description>${todoDescription}</todo:description>
</todo:todoEntry>
</todo:list>
</todo:getTodoListResponse>
But when running the test multiple times via mvn verify there are multiple todoEntry elements in the resulting XML. In order to check this variable list of XML elements that come back in the result. Therefore the check will fail.
The question is, if there is a way to express this dynamic list via the XML validation matcher API.
I got a working solution which is based on the groovy validator like this:
assert root.list.children().size() > 1 (getTodoListResponseValidator.groovy)
But I would rather like to see this working through the XML validation. It seems there is something similar called #matchesXml(), but from the docs it is not clear for me if this is suitable for the described use case.
Thx in advance.
Bye
Mario
Bottom line this is just a bad designed test for the todo-list demo. Integration tests should always operate on a well-known state of the application under test. And the tests should always leave a clean state for other tests to come. These principles are violated in that particular sample.
In fact the sample that you mention is just a demo and therefore not written as a full qualified real world example. Following from that the tests are not working when executed multiple times.
To fix this I would recommend to clear the todo list in a before-test step so you always operate on an empty list. Another possibility would be to use XPath validation instead of comparing the complete list of entries. The XPath validation can check the amount of list entries to be greater that zero for instance (just like you did in the groovy script).
In addition to that you could write a XPath expression that only validates the last entry in that list of todos returned by the server. Something like that
<validate path="count(//todo:todoEntry)" value="#greaterThan(0)#" result-type="number"/>
<validate path="//todo:todoEntry[last()]/todo:title" value="${todoName}"></validate>
Related
Using java 1.8, maven-jaxb2-plugin:0.14.0, and JAXB 2.3.0
when I generate java classes from XSD files, and some classes are too simple, JAXB decides to skip them. Instead, it puts a #XmlElementWrapper annotation.
Example:
<xs:complexType name="AAAA">
<xs:sequence>
<xs:element name="eeee" type="BBBB" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
Turns into
#XmlElementWrapper(namespace = ...)
#XmlElement(namespace = ....)
protected List<BBBB> eeee;
in the logs, I see:
[INFO] Replacing field [eeee AAAA]
In this particular care this optimization does not help me, I would prefer to see the classes as I designed the XSD (eg. AAAA turned into a Java class).
Is there a way to force JAXB into generating all classes and stop running "Replacing field" step?
I'm not sure that I understand correctly. It will be better if you publicate full xsd model and original generated java class/expected class.
But, may be using refernce will help you
<xs:complexType name="AAAA">
<xs:sequence>
<xsd:element ref="eeee" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="eeee">
<xs:sequence>
<xs:element name="eeee" type="BBBB" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
What are the conceptual and technical disadvantages of this request/response structure:
A)
<xs:element name="OrderRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="OrderID" type="xs:integer"/>
<xs:element name="OrderType" type="xs:integer"/>
<xsd:element name='OrderAttributes' type='xsd:string'/>
</xs:sequence>
</xs:complexType>
</xs:element>
where OrderAttributes element will contain string in the following XML structure:
<OrderName> xy </OrderName>
<OrderDate> xy </OrderDate>
<OrderDetails> xy </OrderDetails>
....lots of other attributes
compared to this request/response structure
B)
<xs:element name="OrderRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="OrderID" type="xs:integer"/>
<xs:element name="OrderType" type="xs:integer"/>
<xsd:element name="OrderAttributes">
<xs:complexType>
<xs:sequence>
<xs:element name="OrderName" type="xs:string"/>
<xs:element name="OrderDate" type="xs:date"/>
<xs:element name="OrderDetails" type="xs:string"/>
....lots of other attributes
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
I need to design web service interface for orders processing, and I am thinking about the two alternatives mentioned above.
Version A, is more generic, so interface doesn't need to change, when OrderAttributes structure changes in any way.
But schema validation is not possible.
And my question is, what are other disadvantages compared to version B. I am analyst, not programmer, so I cannot say, if there is some impact on parsing requests, generating code from contract etc...
First note that your generic use of the word attribute to refer to a property can be confusing in XML, where attribute refers to a specific construct that stands apart from element:
<element attribute="attribute value">
<childElement>child element value</childElement>
</element>
Then, while doing design, you might consider which properties you wish to represent as XML attribute and which you wish to represent as XML elements. See XML attribute vs XML element for help deciding.
Regarding your A vs B proposed designs, note that A simply is not viable -- you cannot have unescaped markup within an element declared to have xs:string content as you've shown. Furthermore, A would then require further parsing of the OrderAttributes contents anyway whereas B would leverage the XML parser to process OrderAttributes contents. (And, like you said, B would not leverage XSD validation either.)
For future expansion, consider instead the use of xs:any, which supports various interpretations of wildcard contents via its processContents attribute values of strict, lax, or skip.
I'm going to generate java code from the xsd. I want to know how to remove xsd element when converting xsd to java using jaxb. My goal is to ignore message
Ex:
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="message"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Java Variables
#XmlElement
protected String name;
In here you can see that message element got removed. I want to know how to do that?
If I understand you correctly, to sum it up you want to ignore a mandatory element and still want the result to validate correctly. My short answer is that this is contradictory and does not make sense. JAXB is built to do it correctly and you want do it wrongly(?).
You have several options, eg.
Live with the extra constructor argument.
Generate no-arg constructor instead.
Don't generate, but hand code JAXB annotated classes. Maybe turn off some validation.
Don't use JAXB, use something else (dom4j et. al.) or handcraft the xml
Possibly you can add some overriding in a binding file or even a plug-in, but I wouldn't think it was worth it.
Can you alter the .xsd ?
The current Element "note" tells that both "name" and "message" are mandatory. If you want "message" to be conditional you probably need to add minOccurs="0" attribute:
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="message" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
I want to parse XML schema and then fetch elements from schema in that if there is complex object then that attributes should be fetch with prefix as main complex type.
for instance
<xs:element name="address" >
<xs:complexType>
<xs:sequence>
<xs:element name="city" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
<xs:element name="zipcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Address is complex type if we want to fetch zipcode then it should be like 'address.zipcode'
Is there a way to do this or we have to check manually for type and create fields.
below is XML schema.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="empId" type="xs:integer"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="lastName" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="address" >
<xs:complexType>
<xs:sequence>
<xs:element name="city" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
<xs:element name="zipcode" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
Extracting information from raw schema documents is challenging unless you know that the schema will be restricted to use a subset of the language: for example, that it will not use named model groups, or substitution groups, or complex types derived by extension.
It's easy to write something (e.g. in XSLT) that works with your examples - or at least, it would be easy if we had a clearer picture of what output you wanted - but writing something that can handle ANY schema is much more difficult.
It may be better to work with the compiled representation of a schema produced by a "real" schema processor. For example Xerces has an API allowing access to the "schema components" produced by the schema compiler, and Saxon has an option to produce an SCM file (schema component model) which is an XML file containing the same information; at this level you don't have to cope with all the variety of ways the source schema might have been written.
I am trying to construct an XML document using org.w3c.dom.Document to create some XML for another existing tool. The problem I am having is that the tool seems to have the XML namespaces in a strange way. How can I replicate this using the Java API's?
<ns1:myroot xmlns:ns1="http://foo.com/ns1/">
<ns2:bar xmlns:ns2="http://foo.com/xml/bar/">
<ns2:bar_thing>abc</ns2:bar_thing>
</ns2:bar>
<ns3:data xmlns:ns3="http://foo.com/xml/special-ns">
<!--These are not namespaced for some reason. If I use the ns3 prefix, or
use a default xmls="...", the tool fails to load the document, saying the
elements have invalid values.
-->
<a>Element without namespace</a>
<b>
<bi>1</bi>
<bii>2</bii>
</b>
</ns3:data>
</ns1:myroot>
I can build most of the document easily with createElementNS and setAttributeNS. However I can't get the ns3:data contents to be correct.
Trying to use the non-namespace createElement still left an xmlns="http://foo.com/xml/special-ns"> on my a and b elements, as did using createElementNS with an empty namespace, and obviously a non-empty namespace puts them in a namespace.
The schema for http://foo.com/xml/special-ns has a bunch of declarations like these below, not sure what the tns thing is about, but otherwise does not seem special (although I am not 100% sure the tool actually does anything with the XSD and I don't have access to the source).
<xs:schema version="1.0" targetNamespace="http://foo.com/xml/special-ns">
<!--Bunch of xs:element such as this-->
<xs:element name="data" type="tns:data" />
<!--types declared after-->
<xs:complexType name="data">
<xs:sequence>
<xs:element name="a" type="tns:aDataObj" minOccurs="0"/>
<xs:element name="b" type="tns:bDataObj" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="aDataObj">
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9 ]+" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="bDataObj">
<xs:sequence>
<xs:element name="bi" type="xs:string"/>
<xs:element name="bii" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>