Create Element with atom as prefix using JAXB annotations - java

I'm trying to create an xml element which i want to have as prefix the atom.
I know that i can't do this:
#XmlElement(prefix="atom")
And create
<XmlAttribute>
<atom:link ...>
</XmlAttribute>
Is there a possible way to do this or not?

Yes, you just need to define the namespace corresponding to this prefix:
#XmlElement(name="link", namespace="..")
this will just add the namespace corresponding to the atom prefix to your link element. If your question is about specifically getting atom as the prefix for this namespace, then please look at this question: Is it possible to customize the namespace prefix that JAXB uses when marshalling to a String?

Related

JAXB multiple namespaces with same prefix

This is my first question on StackOverflow in general, so please bear with me.
I have an issue with marshalling XML that uses the default prefix for different namespaces. Each element that uses the default prefix should specify its namespace in its opening tag. An example what I'm trying to achieve would be something like this (simplified):
<parent xmlns="parentNamespace" xmlns:cd1="child1Namespace">
<cd1:child1/>
<child2 xmlns="child2Namespace">
...
</child2>
<child3 xmlns="child3Namespace">
...
</child3>
</parent>
I have tried setting namespaces prefixes in package-info.java of the object I'm trying to marshall using annotations like this:
#javax.xml.bind.annotation.XmlSchema(
namespace = "parentNamespace",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
xmlns = {
#XmlNs(prefix="",parentNamespace"),
#XmlNs(prefix="cd1", namespaceURI="child1Namespace"),
#XmlNs(prefix="", namespaceURI="child2Namespace"),
#XmlNs(prefix="", namespaceURI="child3Namespace")
}
)
But the end result is something like this:
<ns1:parent xmlns:ns1="parentNamespace" xmlns:cd1="child1Namespace" xmlns="child2Namespace xmlns:ns2="child3Namespace"<
<cd1:child1/>
<child2>
...
</child2>
<ns2:child3>
...
</ns2:child3>
</ns1:parent>
Which really is a valid XML, but unfortunately for reasons that are outside my control isn't good enough (doesn't pass validation). Also note that solution using Java 8 is highly preferable as I wouldn't want to mess with NamespacePrefixMapper if at all possible (if it even works).
So the question is: Is it possible to generate XML using JAXB that uses same prefix for multiple namespaces and how?

How to remove namespace prefix from XML response using XSD?

I have generated Java classes from an XSD, and in my XML responses I am getting a ns2: prefix which I do not need.
For example, I am getting this response:
<ns2:location xmlns:ns2="http://www.example.com/">
<ns2:response/>
</ns2:location>
But the response I am expecting is as follows:
<location>
<response/>
</location>
Your example shows not just a namespace prefix (ns2) declaration but also an actual namespace (http://www.example.com/ for the location and response elements) as not being desired.
If you have full control over the XSD, you can remove the
targetNamespace="http://www.example.com/"
attribute from the xs:schema element in the XSD. Elements of XML documents conforming to this XSD will then no longer be in any namespace, and your generated Java classes will reflect this new setting.
However, be aware that deleting (or changing) targetNamespace effectively changes the names of the components defined in the XSD. Think twice about making such a change if the XSD is defined by another party or otherwise already in use by others.

How to tell JAXB to add noNameSpaceSchemaLocation attribute

i have a certain class hierarchic which is transformed to XML using JAXB.
i want the created XML to have the xsi:noNamespaceSchemaLocation and xmls:xsi attributes in the head element ( xsi:noNamespaceSchemaLocation="Something.xsd" xmls:xsi="http://www.w3.org/2001/XMLSchema-instance").
i dont want JAXB do use the schema in any way - just store these attributes and the values.
is there a specific annotation for this? i could create just a constant XmlAttribute but it seems wrong...
thanks
You can set the JAXB_NO_NAMESPACE_SCHEMA_LOCATION on the Marshaller like the following:
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "address.xsd");

How to detect required XML attributes?

I have an XML content without defined attributes, like this:
<rootElement>
<subElement1/>
</rootElement>
I want to populate this XML content with required attributes defined in XML Schema (XSD) for this XML.
For example, according to XSD subElement1 has required attribute 'id'.
What is the best way (for Java processing) to detect that and add such attributes to XML?
We need to add required attributes and set appropriate values for them.
As a result for example above we need to have the following XML:
<rootElement>
<subElement1 id="some-value"/>
</rootElement>
In the XML schema definition, i.e. XSD file, attributes are optional by default. To make an attribute required, you have to define:
<xs:attribute name="surname" type="xs:string" use="required"/>
You will find a very good introduction on XML and XML Schema Definitions, i.e. XSD, on W3 Schools.
In Java the equivalent of defining a XML schema is using JAXB, i.e. Java API for XML Binding that is included into Java SE. There you would define, e.g.
#XmlRootElement
public class Person { public #XmlAttribute(required=true) String surname; }
Hope this could clarify your question.
I would suggest you to use JAXB for that. Search the Internet for tutorials.
Steps to proceed further with JAXB,
Generate Java files using JAXB by providing the schema
Unmarshal your XML to generated Java classes (beans). Don't do validation or set validation handler here.
Populate those classes with appropriate values. required elements can be found using annotation look up. JAXB annotation for element would look like something, #XmlElement(name = "ElementName", required = true). And an attribute annotation would be something similar to this, #XmlAttribute(required = true)
Marshal your bean back to XML. You can validate your bean using ValidationHandler, while marshalling. Below is the sample code snippet,
marshller = JAXBContext.newInstance(pkgOrClassName).createUnmarshaller();
marshller.setSchema(getSchema(xsd)); // skip this line for unmarshaller
marshller.setEventHandler(new ValidationHandler()); // skip this line for unmarshaller
Use a DOM parser.Has methods to traverse XML trees, access, insert, and delete nodes
I have had the same idea of Cris but I think that with this validator you don't have information about the point in which you have had the error.
I think that you have to create or extend your own validator.

Add Xml namespace using Jaxb

I am creating amazon feed, the feed xml should be like:
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
I am using jaxb to generate xml files from java classes, I used NamespacePrefixMapperImpl from jaxb samples to add namespaces to the xml. But currently it generates the root like:
<AmazonEnvelope xmlns:xsi:noNamespaceSchemaLocation="amzn-envelope.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
how I can remove the xmlns from amzn-envelope.xsd??
Here's the mapping I used in NamespacePrefixMapperImpl
if( "http://www.w3.org/2001/XMLSchema-instance".equals(namespaceUri) )
return "xsi";
if("amzn-envelope.xsd".equals(namespaceUri))
return "xsi:noNamespaceSchemaLocation";
I found a property at Marshaller that can add the amzn-envelope.xsd:
marshaller.setProperty("jaxb.noNamespaceSchemaLocation", "amzn-envelope.xsd");
and left the NamespacePrefixMapper to add the "http://www.w3.org/2001/XMLSchema-instance".
Hope this helps others.
If I understand your intent, your document has a default namespace, and you're trying to add the schemalLocation for that namespace.
NamespacePrefixMapper won't let you do this, it's useful only for picking a prefix for a namespace. There are no namespaces in this document, and so no useful way of using NamespacePrefixMapper. It can't be used for adding schemaLocation hints - those are treated specially by JAXB, and you're just confusing it.
Are you sure you need the noNamespaceSchemaLocation="amzn-envelope.xsd" at all? Have you tried sending it to the web service without it?

Categories

Resources