简体   繁体   中英

Java: write XML according to user defined XSD

I'm writing a tool to transform CSV formatted data into XML. The user will specify the parsing method and that is: the XSD for the output, which field in the CSV goes in which field of the resulting XML.

(very simplified use-case) Example:

CSV

Ciccio;Pippo;Pappo
1;2;3

XSD

(more stuff...)
<xs:element name="onetwo">
<xs:element name="three">
<xs:element name="four">

USER GIVES RULES

   Ciccio -> onetwo
   Pippo -> three
   Pappo -> four

I've implemented this in C# using Dataset, how could I do it in Java? I know there's DOM, JAXB etc. but it seems XSD is only used to validate an otherwise created XML. Am I wrong?

Edit: Everything needs to be at runtime. I don't know what kind of XSD I'll receive so I cannot instantiate objects that don't exist nor populate them with data. So I'm guessing the xjc is not an option.

Since you have the XSD for your output XML file, the best way to create this XML would be by using Java Architecture for XML Binding (JAXB). You might want to refer to: "Using JAXB" tutorial to give you an overview of how to go about using this for your requirement.

The basic idea is as follows:

  • Generate JAXB Java classes from an XML schema, ie the XSD that you have
  • Use schema-derived JAXB classes to unmarshal and marshal XML content in a Java application
  • Create a Java content tree from scratch using schema-derived JAXB classes
  • Unmarshal the data to your output XML file.

Here's another tutorial that you might find informative.

This is still work in progress, but you could recurse over the XSD writing out elements as you find them to a new document tree.

public void run() throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new InputSource(new FileReader(
            "schema.xsd")));

    Document outputDoc = builder.newDocument();

    recurse(document.getDocumentElement(), outputDoc, outputDoc);

    TransformerFactory transFactory = TransformerFactory.newInstance();
    Transformer transformer = transFactory.newTransformer();
    StringWriter buffer = new StringWriter();
    transformer.transform(new DOMSource(outputDoc),
            new StreamResult(buffer));
    System.out.println(buffer.toString());
}

public void recurse(Node node, Node outputNode, Document outputDoc) {

    if (node.getNodeType() == Node.ELEMENT_NODE) {
        Element element = (Element) node;
        if ("xs:element".equals(node.getNodeName())) {
            Element newElement = outputDoc.createElement(element
                    .getAttribute("name"));
            outputNode = outputNode.appendChild(newElement);

           // map elements from CSV values here?
        }
        if ("xs:attribute".equals(node.getNodeName())) {
           //TODO required attributes
        }
    }
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        recurse(list.item(i), outputNode, outputDoc);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM