We are using schemagen to create an XSD from some annotated POJOs.
Here is our ant target
<target name="generate-xsd" depends="compile">
<taskdef name="schemagen" classname="com.sun.tools.jxc.SchemaGenTask"
classpathref="xjc.classpath"/>
<schemagen srcdir="src" destdir="generated" includeantruntime="false">
<include name="com/acme/exam/delivery/records/**"/>
<schema namespace="http://www.acme.com/deliverylog"
file="deliverylog.xsd"/>
<schema namespace="" file="supplemental.xsd"/>
</schemagen>
</target>
This is generating
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://www.acme.com/deliverylog"
xmlns:tns="http://www.acme.com/deliverylog"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Where does the tns namespace come from and what does it signify?
That infomration comes from the package level annotation #XmlSchema which can be found in the package-info class. See below for an example.
package-info
#XmlSchema(
namespace = "http://www.acme.com/deliverylo",
elementFormDefault = XmlNsForm.QUALIFIED)
package example;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Sample XML
elementFormDefault specifies which elements should be namespace qualified (true = all, false = only global elements), and targetNamespace defines what the namespace is.
<foo xmlns="http://www.acme.com/deliverylog">
<bar>Hello World</bar>
</foo>
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
Related
I am having the below XML:
<orders>
<order xmlns:amz="http://www.amazon.co">
<amz:comp>amz</amz:comp>
</order>
<order xmlns:ebay="http://www.ebay.co">
<ebay:comp>ebay</ebay:comp>
</order>
</orders>
I checked the xpath expressions like //orders/order it is working but in groovy it is not working I'm not getting what is wrong.
Below is the code that I am using:
import groovy.xml.*;
def source = '''<orders>
<order xmlns:amz="http://www.amazon.co">
<amz:comp>amz</amz:comp>
</order>
<order xmlns:ebay="http://www.ebay.co">
<ebay:comp>ebay</ebay:comp>
</order>
</orders>'''
def root = new XmlSlurper().parseText(source).declareNamespace([
amz: "http://www.amazon.co",
ebay: "http://www.ebay.co"
])
println root.orders
println root.orders.order."amz:comp"
I am not getting any output for the above code.
In your example, root variable refers to the <orders> element, so when you call root.orders it is like you were looking for
<orders>
<orders>...</orders>
</orders>
Rename root variable to orders and do
println orders
println orders.order."amz:comp"
to get the following output:
amzebay
amz
Would like to output the following at the head of xml
I can find lots on parsing and validating, but not so much on creation/output
I can find some documentation on QName but how do I output
`
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://service-spi.web.cern.ch/service-spi/app /releases/GDML/schema/gdml.xsd">`
Use QName to create the attribute (noNamespaceSchemaLocation) that is bound to the http://www.w3.org/2001/XMLSchema-instance namespace.
from lxml.etree import QName, Element, tostring
qname = QName("http://www.w3.org/2001/XMLSchema-instance", "noNamespaceSchemaLocation")
attr_dict = {qname: "http://service-spi.web.cern.ch/service-spi/app /releases/GDML/schema/gdml.xsd"}
gdml = Element("gdml", attr_dict)
print(tostring(gdml, encoding="UTF-8", standalone=False).decode())
Output:
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://service-spi.web.cern.ch/service-spi/app /releases/GDML/schema/gdml.xsd"/>
The namespace declaration (xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance") is created automatically.
Thanks - I already did it another way
NS = 'http://www.w3.org/2001/XMLSchema-instance'
location_attribute = '{%s}noNameSpaceSchemaLocation' % NS
gdml = ET.Element('gdml',attrib={location_attribute: 'http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd'})
print(gdml.tag)
While looking at XML schema examples, I have seen the following case (in xml schema test suite, microsoft schema schG1_a/b/c.xsd):
Conceptually, schema document A (target a) imports schema document B (target b) which in turn imports schema document C (target c).
My reading of the schema specs is that A must directly import C in order to refer to anything in C (import is not transitive). It does not. This is not an issue because A itself does not refer to anything in C or even in B. It defines just an element 'root' that is a sequence of 'any' from '##any' namespace with processContents 'strict'.
Now the problem is that the instance document schG1.xml is referring to the schema A only although it uses global elements defined in A, B and C as children of the 'root' element in A. Because processContents is 'strict' the schema A should be used to validate the instance elements (as children of 'root'). I understand that it can do it for the elements defined in A and B (directly imported in A) but I fail to understand how it can validate elements from C since they were never directly seen in A.
However the test is supposed to be valid. I am sure I must be missing something...
schG1_a.xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="ns-a" xmlns="ns-a">
<xsd:import namespace="ns-b" schemaLocation="schG1_b.xsd"/>
<xsd:element name="e1" type="xsd:int"/>
<xsd:element name="root">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:any namespace="##any" processContents="strict"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
schG1_b.xsd
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="ns-b" xmlns="ns-b">
<xsd:import namespace="ns-c" schemaLocation="schG1_c.xsd" />
<xsd:element name="e1" type="xsd:boolean" />
</xsd:schema>
schG1_c.xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="ns-c" xmlns="ns-c">
<xsd:element name="e1" type="xsd:string" />
</xsd:schema>
schG1.xml:
<a:root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="ns-a schG1_a.xsd"
xmlns:a="ns-a" xmlns:b="ns-b" xmlns:c="ns-c">
<a:e1>123</a:e1>
<b:e1>true</b:e1>
<c:e1>foo</c:e1>
</a:root>
I use an XML Schema Definition and JAXB to generate Java classes with proper #XmlElement or #XmlRootElement annotations.
Since the schema has some deep nesting in it (not my choice), I'd rather use jxpath to access deeply buried classes using an XPath (rather than cumbersome daisy-chain of .getThat() and that != null).
The problem is that some of the XML element names contain dashes, e.g. foo-bar. When I try to access elements using org.apache.jxpath, I need to rewrite my XPath so that such names are camel-cased instead (fooBar) like the name of the actual Java objects. Is there any way to tell jxpath to find the elements using the XPath corresponding to the XML element names (instead of the camel-cased Bean names)?
I think it is related to this question, however in my case I don't actually case what kind of tricks and decorations are used on the auto-generated classes, as long as xjc can do it.
Here is a simple example to illustrate the issue.
First, a small XSD file:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="record">
<xs:complexType>
<xs:sequence>
<xs:element name="foo-bar" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Compile it...
xjc -p org.pd.jx example.xsd
Here is the xjc-generated Record.java class (minus comments):
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {"fooBar"})
#XmlRootElement(name = "record")
public class Record {
#XmlElement(name = "foo-bar", required = true)
protected String fooBar;
public String getFooBar() {return fooBar;}
public void setFooBar(String value) {this.fooBar = value;}
}
Then, trying to access the data via jxpath (in practice I have to deal with lots of deeply nested classes), one can see below that the correct XPath ("foo-bar") doesn't work, but a camel-cased version does.
Record record = new Record();
record.setFooBar("hello world");
JXPathContext context = JXPathContext.newContext(record);
context.setLenient(true);
String a = (String)context.getValue("foo-bar", String.class); // is null
String b = (String)context.getValue("fooBar", String.class); // "hello world"
I believe JXPath operates on an objects properties and not the XML elements they correspond to. I do not believe that JXPath parses any of the JAXB metadata so it wouldn't know the XML nodea you have mapped. What you are seeing appears to be the expected behaviour.
I have created a sample XML. And trying to Read by using LINQ
here is the code:
XElement root = XElement.Load("C:\\............\\TestData.xml");
IEnumerable<Xelement> address = from tt in root.Elements("Test")
select tt;
I am getting compile time error at select statement :
Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>'
to 'System.Collections.Generic.IEnumerable<EvalTest.Xelement>'.
An explicit conversion exists (are you missing a cast?)
XML:
<?xml version="1.0" encoding="utf-8" ?>
<TestData>
<Test Method="1">
<ID>1</ID>
<Submitter> Ritvij</Submitter>
<Date>11/5/2013 2:51:57 PM </Date>
</Test>
<Test Method="2">
<ID>1</ID>
<Submitter> Ritvij</Submitter>
<Date>11/5/2013 2:51:57 PM </Date>
</Test>
</TestData>
root.Elements returns an IEnumerable<XElement> (with a capital "E"), but you're trying to assign it to IEnumerable<Xelement> (lower case "e").
Either modify your code to use XElement or use var:
IEnumerable<XElement> address = from tt in root.Elements("Test") select tt;
var address = from tt in root.Elements("Test") select tt;