如何在Java中将JSON转换为XML

时间:2013-10-24 04:59:13

标签: java xml json translation

我写了一些Java代码,它应该将JSON输入文件转换为等效的XML文件。我在stackoverflow上使用了其他问题的一些答案。但是,我收到一个错误:

[Fatal Error] :1:123: The markup in the document following the root element must be well-formed.
Exception in thread "main" org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 123; The markup in the document following the root element must be well-formed.
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:251)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:300)
    at TranslateJSONtoXML.stringToDom(TranslateJSONtoXML.java:34)
    at TranslateJSONtoXML.main(TranslateJSONtoXML.java:43)

为什么会出现这个错误?我假设JSON输入格式正确。 所以,这是代码:

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import org.json.JSONObject;
import org.json.XML;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;

public class TranslateJSONtoXML {   
public static String readFile(String pathname) throws IOException {

    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int)file.length());
    Scanner scanner = new Scanner((Readable) new BufferedReader(new FileReader(file)));
    String lineSeparator = System.getProperty("line.separator");

    try {
        while(scanner.hasNextLine()) {        
            fileContents.append(scanner.nextLine()).append(lineSeparator);
        }
        return fileContents.toString();
    } finally {
        scanner.close();
    }
}

public static Document stringToDom(String xmlSource) 
        throws SAXException, ParserConfigurationException, IOException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    return builder.parse(new InputSource(new StringReader(xmlSource)));
}

public static void main(String[] args) 
        throws SAXException, ParserConfigurationException, IOException {
    String jsonString = readFile("/Users/monicamarcus/Downloads/Attachments_20131023/edl.json");
    JSONObject o = new JSONObject(jsonString);
    String xml = org.json.XML.toString(o);
    System.out.println(xml);
    Document doc = stringToDom(xml);

    System.out.println(doc.getDocumentURI());
}

}

错误来自行返回builder.parse(new InputSource(new StringReader(xmlSource)));

这是我得到的XML。它显然不是很好,但我不知道为什么我会这样:

<javascript>function textCounterEval(e,t){var n=t;var r=n.length;if(r&gt;=e){return    true}else{return false}}</javascript>
<title>Request Conversion</title>
<configParams>param1</configParams>
<configParams>param2</configParams>
<instructions>** Fields with an asterisk are required.</instructions>
<name>RequestJSON.eDoc.Form</name>
<createInstructions>** Fields with an asterisk are required.</createInstructions>
<eventNotificationURL>http://localhost:8080/xx-xxx/xxx.jsp</eventNotificationURL>
<fieldDefs>
    <attributeName>RequestChange.eDoc.isUrgent.RuleAttribute</attributeName>
    <title>URGENT</title>
    <validation><message>Please Select a Campus.</message>
    <customValidator>function addEvent(e,t,n,r){if(e.addEventListener){e.addEventListener(t,n,r);return true}else if(e.attachEvent){var i=e.attachEvent(&apos;on&apos;+t,n);return i}else{e[&apos;on&apos;+t]=n}}</customValidator>
<regex>[^Select]</regex>
<required>true</required>
    </validation><name>isUrgent</name>
    <value>no</value>
    <display>
        <values>
            <title>--- Select ---</title>
        </values>
        <values>
            <title>Group1</title>
            <value>sampleGroup1</value>
        </values>
        <values>
            <title>Group2</title>
            <value>sampleGroup2</value>
        </values>
  <valuesGroup>
       <values>
          <title>NO</title>
          <value>NO</value>
       </values>
       <values>
           <title>YES</title>
           <value>YES</value>
       </values>
  <dependsOn>
        <field>
            <name>abc</name>
            <value>XYZ</value>
        </field>
  </dependsOn>
  </valuesGroup>
        <type>select</type>
        <meta>
           <name>cols</name>
           <value>60</value>
        </meta>
</display>
  <lookup>
      <fieldConversions>conversions</fieldConversions>
       <businessObjectClassName>org.xxx.xxxx</businessObjectClassName>
  </lookup>
  </fieldDefs>
  <fieldDefs>
  <title>Date and Time for Change: MM/DD/YYYY</title>
  <validation>
     <message>Enter a valid date in the format mm/dd/yyyy.</message>
     <regex>^[0-1]?[0-9](/|-)[0-3]?[0-9](/|-)[1-2][0-9][0-9][0-9]$</regex>
     <required>true</required>
  </validation>
      <name>dateOfChange</name>
      <display>
         <type>text</type>
      </display>
  </fieldDefs>
  <fieldDefs>
   <title>Description of the Change</title>
   <validation>
       <message>Enter a description of the change.</message>
       <required>true</required>
   </validation>
       <name>descriptionOfChange</name>
       <display>
           <type>textarea</type>
           <meta>
               <name>rows</name>
               <value>5</value>
           </meta>
           <meta>
                <name>cols</name>
                <value>60</value>
           </meta>
       </display>
   </fieldDefs><
       validations>
            <message>If Request is OTHER, please enter Other Request.</message>
            <expression>(wf:field(&apos;reason&apos;) = &apos;Other&apos; and
   not(wf:empty(wf:field(&apos;otherDescription&apos;)))) or (wf:field(&apos;reason&apos;) != 
   &apos;Other&apos; and wf:empty(wf:field(&apos;otherDescription&apos;)))
             </expression>
       </validations>
          <attributes>
              <name>NetworkIdRole1Attribute</name>
              <fields>
                 <attributeField>user1Id</attributeField>
                 <edlField>RoleAdHoc</edlField>
              </fields>
         </attributes>
         <attributes>
              <name>NetworkIdRole2Attribute</name>
              <fields>
                  <attributeField>user2Id</attributeField>
                  <edlField>RoleAdHoc</edlField>
              </fields>
         </attributes>
    <security>Defines security for the edl document
    </security>

我也发布了JSON文件。不过,它看起来很好。

{
    "name": "RequestJSON.eDoc.Form",
    "title": "Request Conversion",
    "configParams": [
        "param1",
        "param2"
    ],
    "security": "Defines security for the edl document",
    "eventNotificationURL": "http://localhost:8080/xx-xxx/xxx.jsp",
    "createInstructions": "** Fields with an asterisk are required.",
    "instructions": "** Fields with an asterisk are required.",
    "validations": [
        {
            "expression": "(wf:field('reason') = 'Other' and not(wf:empty(wf:field('otherDescription')))) or (wf:field('reason') != 'Other' and wf:empty(wf:field('otherDescription')))",
        "message": "If Request is OTHER, please enter Other Request."
        }
                 ],
    "attributes": [
        {
            "name": "NetworkIdRole1Attribute",
            "fields": [
                {
                    "attributeField": "user1Id",
                    "edlField": "RoleAdHoc"
                }
            ]
        },
        {
            "name": "NetworkIdRole2Attribute",
            "fields": [
                {
                    "attributeField": "user2Id",
                    "edlField": "RoleAdHoc"
                }
            ]
        }
    ],
    "javascript": "function textCounterEval(e,t){var n=t;var r=n.length;if(r>=e){return true}else{return false}}",
    "fieldDefs": [
        {
            "attributeName": "RequestChange.eDoc.isUrgent.RuleAttribute",
            "name": "isUrgent",
            "title": "URGENT",
            "value": "no",
            "display": {
                "type": "select",
                "meta": [
                    {
                        "name": "cols",
                        "value": "60"
                    }
                ],
                "values": [
                    {
                        "title": "--- Select ---"
                    },
                    {
                        "title": "Group1",
                        "value": "sampleGroup1"
                    },
                    {
                        "title": "Group2",
                        "value": "sampleGroup2"
                    }
                ],
                "valuesGroup": {
                    "dependsOn": {
                        "field": {
                            "name": "abc",
                            "value": "XYZ"
                        }
                    },
                    "values": [
                        {
                            "title": "NO",
                            "value": "NO"
                        },
                        {
                            "title": "YES",
                            "value": "YES"
                        }
                    ]
                }
            },
            "lookup": {
                "businessObjectClassName": "org.xxx.xxxx",
                "fieldConversions": "conversions"
            },
            "validation": {
                "required": "true",
                "regex": "[^Select]",
                "customValidator": "function addEvent(e,t,n,r){if(e.addEventListener){e.addEventListener(t,n,r);return true}else if(e.attachEvent){var i=e.attachEvent('on'+t,n);return i}else{e['on'+t]=n}}",
                "message": "Please Select a Campus."
            }
        },
        {
            "name": "dateOfChange",
            "title": "Date and Time for Change: MM/DD/YYYY",
            "display": {
                "type": "text"
            },
            "validation": {
                "required": "true",
                "regex": "^[0-1]?[0-9](/|-)[0-3]?[0-9](/|-)[1-2][0-9][0-9][0-9]$",
                "message": "Enter a valid date in the format mm/dd/yyyy."
            }
        },
        {
            "name": "descriptionOfChange",
            "title": "Description of the Change",
            "display": {
                "type": "textarea",
                "meta": [
                    {
                        "name": "rows",
                        "value": "5"
                    },
                    {
                        "name": "cols",
                        "value": "60"
                    }
                ]
            },
            "validation": {
                "required": "true",
                "message": "Enter a description of the change."
            }
        }
    ]
}

1 个答案:

答案 0 :(得分:1)

首先,您的XMLified JSON对象不包含XML标头<?xml version="1.0"?>,其次您在XML中有多个根元素,如我在第一条评论中所述。最简单的解决方案是手动添加它们:

StringBuilder builder = new StringBuilder();
builder
    .append("<?xml version=\"1.0\"?>")
    .append("<yourJsonToXmlRootElement>")
    .append(xml)
    .append("</yourJsonToXmlRootElement>");
xml = builder.toString();

然后将xmlstringToDom功能一起使用。

但请注意,我可能还有其他错误尚未检查过。