pankaj gupta
pankaj gupta

Reputation: 31

How to create XML that allows Xml Element to have colon and number of nodes

// I need to create following XML . i have searched a lot but not able to understand how to create this type of xml:

  <CommandInfoDTO ClassName="DomainDTO">
    <Domains>
      <a:string>kochar.com</a:string>
      <a:string>yahoo.com</a:string>
    </Domains>
  </CommandInfoDTO>

// I have created xml that have single node so i used JaxB and Marshaller

@XmlRootElement(name = "CommandInfoDTO")
@XmlAccessorType(XmlAccessType.FIELD)
public class EnforcePasswordDTO {

    @XmlAttribute(name = "ClassName")
    String className = "EnforcePasswordDTO";
    @XmlElement(name = "AllowSpecialCharacters")
    boolean AllowSpecialCharacters = false;
    @XmlElement(name = "ChangeFrequency")
    String changeFrequency = null;
   }

 JAXBContext jc = JAXBContext.newInstance(EnforcePasswordDTO.class);
 Marshaller marshaller = jc.createMarshaller();

<CommandInfoDTO ClassName="EnforcePasswordDTO">
    <AllowSpecialCharacters>true</AllowSpecialCharacters>
    <ChangeFrequency>5</ChangeFrequency>
</CommandInfoDTO>

// But how can i create xml having colon and also have number of nodes.

Upvotes: 3

Views: 1892

Answers (1)

bdoughan
bdoughan

Reputation: 149037

Marshalling - No Problems

To marshal (output) a colon (:) in an element name you simply need to specify it in the name parameter on the corresponding JAXB annotation.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    @XmlElement(name="notANamespacePrefix:bar")
    String bar;

}

Output

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <notANamespacePrefix:bar>Hello World</notANamespacePrefix:bar>
</foo>

Unmarshalling - Special Handling Required

What Won't Work

If you try to unmarshal XML that contains a colon in the element name where the portion before the colon does not correspond to a namespace prefix as follows:

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    File xml = new File("src/forum22088353/input.xml");
    Foo uFoo = (Foo) unmarshaller.unmarshal(xml);

Then you are going to get an exception like the following:

Exception in thread "main" javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; systemId: file:/Users/bdoughan/GIT/EclipseLink-Trunk3/Scratch/src/forum22088353/input.xml; lineNumber: 3; columnNumber: 30; The prefix "notANamespacePrefix" for element "notANamespacePrefix:bar" is not bound.]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:514)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:215)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:184)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
    at forum22088353.Demo.main(Demo.java:21)

What Will Work Instead

You can leverage JAXB with SAX to property process element names with the colon character. This is because by default a SAX parser is not namespace aware.

    SAXParserFactory spf = SAXParserFactory.newInstance();
    SAXParser sp = spf.newSAXParser();
    XMLReader xmlReader = sp.getXMLReader();

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
    xmlReader.setContentHandler(unmarshallerHandler);
    xmlReader.parse(new InputSource("src/forum22088353/input.xml"));
    Foo uFoo = (Foo) unmarshallerHandler.getResult();

Upvotes: 4

Related Questions