0

I am looking for a Java library that can take an XSD schema and create a sample XML document that can then be manipulated. In my simple example i am given an XML that i load, manipulate and print. How can i achieve the same result if i am only given an XSD?

String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
                "<ns0:store_msg xmlns:ns0=\"http://data\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://data sample.xsd \">" + 
                "<item>" +
                "<name>A</name>" +
                "<price>1.1</price>" +
                "</item>" +
                "<item>" +
                "<name>B</name>" +
                "<price>2.2</price>" +
                "</item>" +
                "</ns0:store_msg>";

    // load XML
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = builderFactory.newDocumentBuilder();
    Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));


    // manipulate XML
    Node root = doc.getFirstChild();
    Element el = doc.createElement("item");
    Element name = doc.createElement("name");
    Element price = doc.createElement("price");
    name.setTextContent("C");
    price.setTextContent("2.2");
    el.appendChild(name);
    el.appendChild(price);
    root.appendChild(el);

    // print XML
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

    transformer.transform(new DOMSource(doc), 
         new StreamResult(new OutputStreamWriter(System.out, "UTF-8")));
5
  • You should use JAXB : github.com/javaee/jaxb-v2 Commented Jul 12, 2017 at 16:10
  • Agreed - use JAXB. dzone.com/articles/introduction-to-jaxb-20 Commented Jul 12, 2017 at 16:13
  • Thank you for your response. I am a little confused about the use of JAXB. Pardon the novice question but would JAXB produce source code of a POJO outside of runtime and then this unmarshaled code can be compiled and used, or can JAXB actually create an object at runtime based on the gives schema and the this object could be manipulated and marshalled to raw XML in, lets say, a file ? Commented Jul 12, 2017 at 16:35
  • What you’re asking isn’t really feasible. XSDs are pretty versatile. What would a sample XML document contain for an element declared in the XSD with minOccurs="0"? What would a sample XML document contain for an element whose type is defined with <choice>? Commented Jul 12, 2017 at 17:28
  • @VGR - you are partially correct, but... it is possible by deciding what to do with such things. Actualy many tools do it, at least XMLSpy, SOAPUI - and they ask user to define what to do. Commented Jul 12, 2017 at 17:51

1 Answer 1

1

A. use JAXB (preferable):

  1. pre-step: generate JAXB Java classes out of your XSD, as example by maven-jaxb2-plugin or with other tools or manually calling XJC compiler

  2. when you have needed classes create your root element:

    StoreMsg myStoreMsgRoot = new StoreMsg(); // Class must be what JAXB generated for store_msg element

  3. populate needed elements in it as you wish. as example:

     Item firstItem = new Item();
     firstItem.setName("A");
     firstItem.setPrice(1.1);
     myStoreMsgRoot.getItem().add(firstItem);
    

    and so on

  4. Then marshal your root element with JAXBContext as example to String

    JAXBContext jaxbCtx = JAXBContext.newInstance(StoreMsg.class);
    ByteArrayOutputStream bos = new ByteArrayOutputStream(); jaxbCtx.createMarshaller().marshal(myStoreMsgRoot, bos); String generatedXml = new String(bos.toByteArray()); bos.close();

B. there is a framework to do it - jlibs.

Simple example is here: jlibs - XSInstance.wiki

Aside of that you may need to set bunch of properties to deal with cases @VCR commented about.

From first glance it works somehow.

Just latest versions need dependencies (through Maven as below or jar files in the classpath):

    <!-- https://mvnrepository.com/artifact/in.jlibs/jlibs-xsd -->
    <dependency>
        <groupId>in.jlibs</groupId>
        <artifactId>jlibs-xsd</artifactId>
        <version>2.2.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/in.jlibs/jlibs-xml -->
    <dependency>
        <groupId>in.jlibs</groupId>
        <artifactId>jlibs-xml</artifactId>
        <version>2.1</version>
    </dependency>

    <dependency>
        <groupId>xerces</groupId>
        <artifactId>xerces</artifactId>
        <version>2.4.0</version>
    </dependency>

    <dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        <version>2.11.0-22</version>
    </dependency>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.