Java:根据用户定义的XSD编写XML

Java:根据用户定义的XSD编写XML,java,xml,parsing,csv,xsd,Java,Xml,Parsing,Csv,Xsd,我正在编写一个将CSV格式的数据转换为XML的工具。用户将指定解析方法,即:输出的XSD,CSV中的哪个字段进入结果XML的哪个字段 (非常简化的用例)示例: CSV XSD 我已经在C#中使用Dataset实现了这一点,如何在Java中实现?我知道有DOM、JAXB等,但XSD似乎只用于验证以其他方式创建的XML。我错了吗 编辑: 一切都需要在运行时完成。我不知道我将收到什么样的XSD,所以我无法实例化不存在的对象,也无法用数据填充它们。所以我猜xjc不是一个选项。因为您的输出XML文件有XS

我正在编写一个将CSV格式的数据转换为XML的工具。用户将指定解析方法,即:输出的XSD,CSV中的哪个字段进入结果XML的哪个字段

(非常简化的用例)示例:

CSV

XSD

我已经在C#中使用Dataset实现了这一点,如何在Java中实现?我知道有DOM、JAXB等,但XSD似乎只用于验证以其他方式创建的XML。我错了吗

编辑:
一切都需要在运行时完成。我不知道我将收到什么样的XSD,所以我无法实例化不存在的对象,也无法用数据填充它们。所以我猜xjc不是一个选项。

因为您的输出
XML
文件有
XSD
,所以创建这个
XML
的最佳方法是使用Java Architecture for XML Binding(JAXB)。您可能希望参考:教程,以概述如何根据您的需求使用此工具

基本思路如下:

  • 从XML模式生成JAXB Java类,即您拥有的
    XSD
  • 使用模式派生的JAXB类在Java应用程序中解组和封送XML内容
  • 使用模式派生的JAXB类从头开始创建Java内容树
  • 将数据解组到输出
    XML
    文件中

您可能会发现这些信息。

这项工作仍在进行中,但您可以在发现新文档树中的元素时,在XSD上循环写出这些元素

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);
    }

}
public void run()引发异常{
DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance();
DocumentBuilder=factory.newDocumentBuilder();
Document Document=builder.parse(新输入源(新文件读取器(
“schema.xsd”);
Document outputDoc=builder.newDocument();
递归(document.getDocumentElement(),outputDoc,outputDoc);
TransformerFactory transFactory=TransformerFactory.newInstance();
变压器=transFactory.newTransformer();
StringWriter缓冲区=新StringWriter();
transformer.transform(新的DOMSource(outputDoc)),
新的流结果(缓冲区);
System.out.println(buffer.toString());
}
公共无效递归(节点节点、节点outputNode、文档outputDoc){
if(node.getNodeType()==node.ELEMENT\u node){
元素=(元素)节点;
if(“xs:element”.equals(node.getNodeName())){
元素newElement=outputDoc.createElement(元素
.getAttribute(“名称”);
outputNode=outputNode.appendChild(新元素);
//将CSV值中的元素映射到此处?
}
if(“xs:attribute”.equals(node.getNodeName())){
//TODO必需属性
}
}
NodeList list=node.getChildNodes();
对于(int i=0;i
XSD可用于使用JDK附带的工具创建JAXB类,然后可用于编写XML。。。请参见此处的示例:这可能是的副本。我必须承认,我在C#中的实现只考虑了1或2个XSD,现在我想把它做大,但显然没有解决方案。感谢您提供的链接,但我看到的只是如何使用这个名为xjc的工具来生成Java类。我需要在运行时执行所有操作,可能没有在用户机器上安装任何JDK。主要的想法是,我不知道我将收到什么样的XSD,因此我无法以编程方式提供任何绑定。或者,再一次,我错了吗?@Sphaso-不,你没有错,jaxb对你试图做的事情没有意义。jaxb对于静态定义的XSD很有用。我曾经考虑过这样做,但我发现了一些问题:-如果我们在不同的分支中有相同的节点名会怎么样?例如(Xpath表示法)/root/branchOne/samenae--/root/branchTwo/samenae-如何传递xs:element或xs:attribute?您是否在用户指定的每个输出上使用foreach?然而,我可能需要更多地思考您的代码。同时,谢谢!
(more stuff...)
<xs:element name="onetwo">
<xs:element name="three">
<xs:element name="four">
   Ciccio -> onetwo
   Pippo -> three
   Pappo -> four
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);
    }

}