Creating an XML file from XSD from JAXB

28,193

Solution 1

You create an instance of Test and ScreensType but never set any of their properties before marshalling them to XML. Below is the corrected code.

public void generateXml() throws JAXBException, IOException {
    Test test = new Test();
    ScreensType screens = new ScreensType();
    test.getOption1OrOption2OrOption3().add(screens);
    ScreenType screen = new ScreenType();
    screen.setName1("a");
    screen.setName2("b");
    screen.setName3("c");
    screens.getScreen().add(screen);

    File f = new File("new.xml");
    JAXBContext context= JAXBContext.newInstance("com.q1labs.qa.xmlgenerator.model.generatedxmlclasses");
    Marshaller jaxbMarshaller = context.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    jaxbMarshaller.marshal(test, f);
    jaxbMarshaller.marshal(test, System.out);
}

Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Test xmlns="http://ibm.org/seleniumframework">
    <Option3>
        <Screen name1="a" name2="b" name3="c"/>
    </Option3>
</Test>

Solution 2

After trying for couple of days, eventually i was able to create the xml from xsd properly using the code given below. Hope this helps :

           String filename = "<filepath/filename>";

          final Document doc = loadXsdDocument(filename);

       //Find the docs root element and use it to find the targetNamespace
            final Element rootElem = doc.getDocumentElement();
            String targetNamespace = null;
            if (rootElem != null && rootElem.getNodeName().equals("xs:schema")) 
                       {
                targetNamespace = rootElem.getAttribute("targetNamespace");
            }


                        //Parse the file into an XSModel object
            XSModel xsModel = new XSParser().parse(filename);

                        //Define defaults for the XML generation
            XSInstance instance = new XSInstance();
            instance.minimumElementsGenerated = 1;
            instance.maximumElementsGenerated = 1;
            instance.generateDefaultAttributes = true;
            instance.generateOptionalAttributes = true;
            instance.maximumRecursionDepth = 0;
            instance.generateAllChoices = true;
            instance.showContentModel = true;
            instance.generateOptionalElements = true;

                        //Build the sample xml doc
                        //Replace first param to XMLDoc with a file input stream to write to file
            QName rootElement = new QName(targetNamespace, "<xsd file name>");
            XMLDocument sampleXml = new XMLDocument(new StreamResult(System.out), true, 4, null);
            instance.generate(xsModel, rootElement, sampleXml);
        } catch (TransformerConfigurationException e) 
                {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static Document loadXsdDocument(String inputName) {
        final String filename = inputName;

        final DocumentBuilderFactory factory = DocumentBuilderFactory
                .newInstance();
        factory.setValidating(false);
        factory.setIgnoringElementContentWhitespace(true);
        factory.setIgnoringComments(true);
        Document doc = null;

        try {
            final DocumentBuilder builder = factory.newDocumentBuilder();
            final File inputFile = new File(filename);
            doc = builder.parse(inputFile);
        } catch (final Exception e) {
            e.printStackTrace();
            // throw new ContentLoadException(msg);
        }

        return doc;
    }
Share:
28,193
Colin747
Author by

Colin747

Currently writing my thesis on using wearable technology with machine vision to support occupants with Activities of Daily Living while working as a Research Associate within the Smart Environments Research Group and Ulster University.

Updated on February 28, 2020

Comments

  • Colin747
    Colin747 about 4 years

    I'm having trouble creating an XML file from XSD using JAXB below is the XSD file used to create it. (Note: Names have been edited due to confidentiality)

        <?xml version="1.0" encoding="UTF-8"?>
        <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://ibm.org/seleniumframework" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
        <xs:element name="Test" type="sel:Test">
            <xs:complexType>
                <xs:choice minOccurs="1" maxOccurs="unbounded">
                    <xs:element name="Option1" type="sel:Option1Type" xmlns:sel="http://ibm.org/seleniumframework"/>
                    <xs:element name="Option2" type="sel:Option2Type" xmlns:sel="http://ibm.org/seleniumframework"/>
                    <xs:element name="Option3" type="sel:ScreensType" xmlns:sel="http://ibm.org/seleniumframework"/>
                </xs:choice>
            </xs:complexType>
        </xs:element>
    
        <xs:complexType name="ScreensType">
            <xs:sequence>
                <xs:element type="sel:ScreenType" name="Screen" minOccurs="1" maxOccurs="unbounded" xmlns:sel="http://ibm.org/seleniumframework"/>
            </xs:sequence>
        </xs:complexType>
    
        <xs:complexType name="ScreenType">
            <xs:sequence>
                <xs:element name="ScreenData" minOccurs="1" maxOccurs="unbounded" xmlns:sel="http://ibm.org/seleniumframework"/>
            </xs:sequence>
            <xs:attribute type="xs:string" name="name1" use="required" />
            <xs:attribute type="xs:string" name="name2" use="required" />
            <xs:attribute type="xs:string" name="name3" use="required" />
        </xs:complexType>
    
    </xs:schema>
    

    This is the code I am using to try and create the XML:

    public void generateXml() throws JAXBException, IOException {
    
                Test test = new Test();
                ScreensType screens = new ScreensType();
                ScreenType screen = new ScreenType();
                screen.setName1("a");
                screen.setName2("b");
                screen.setName3("c");
    
                File f = new File("new.xml");
                JAXBContext context= JAXBContext.newInstance("com.q1labs.qa.xmlgenerator.model.generatedxmlclasses");
                Marshaller jaxbMarshaller = context.createMarshaller();
                jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    
                jaxbMarshaller.marshal(test, f);
                jaxbMarshaller.marshal(test, System.out);
    
            }
    

    This is the output

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
            <Test xmlns="http://ibm.org/seleniumframework"/>
    

    How can I get the code to output the screens and the screen tag along with it's properties, I'm not sure what I'm doing wrong.

  • Colin747
    Colin747 over 11 years
    That worked! Thanks very much! I'm new to JAXB so you've been a lot of help.
  • bdoughan
    bdoughan over 11 years
    @Colin747 - I happy I could help. BTW, I maintain a Java XML and JSON Binding blog that you may find useful: blog.bdoughan.com
  • Diogo Kollross
    Diogo Kollross over 6 years
    This answer' sample code uses classes from the JLibs project.