用Java解析XML

时间:2014-01-10 12:50:17

标签: java xml parsing xml-parsing

我有这个格式不正确的XML文件,但无论如何我需要解析它。我已经尝试过所有解析选项说DOM / SAX解析但仍然无法实现它,试过this

所以有人可以指导我如何解析这些格式不正确的xml数据。

这是XML文件

<?xml version="1.0" ?>
<Employee>
<Name> Jack
<EMPID> EMP001 <Address> 12 CA, USA</Address> 
</EMPID>
</Name>
</Employee>

解析代码

DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(new File(
                    "new.xml"));

            // normalize text representation
            doc.getDocumentElement().normalize();
            System.out.println("Root element of the doc is "
                    + doc.getDocumentElement().getNodeName());

            NodeList listOfPersons = doc.getElementsByTagName("NAME");
            int totalPersons = listOfPersons.getLength();


            for (int s = 0; s < listOfPersons.getLength(); s++) {

                Node firstPersonNode = listOfPersons.item(s);
                if (firstPersonNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element firstPersonElement = (Element) firstPersonNode;

                    // -------
                    NodeList firstNameList = firstPersonElement
                            .getElementsByTagName("Name");
                    Element firstNameElement = (Element) firstNameList.item(0);

                    NodeList textFNList = firstNameElement.getChildNodes();
                    System.out
                            .println("Name : "
                                    + ((Node) textFNList.item(0))
                                            .getNodeValue().trim());

                    // -------
                    NodeList lastNameList = firstPersonElement
                            .getElementsByTagName("EMPID");
                    Element lastNameElement = (Element) lastNameList.item(0);

                    NodeList textLNList = lastNameElement.getChildNodes();
                    System.out
                            .println("ID : "
                                    + ((Node) textLNList.item(0))
                                            .getNodeValue().trim());

                    // ----
                    NodeList ageList = firstPersonElement
                            .getElementsByTagName("Address");
                    Element ageElement = (Element) ageList.item(0);

                    NodeList textAgeList = ageElement.getChildNodes();
                    System.out.println("Address : "
                            + ((Node) textAgeList.item(0)).getNodeValue()
                                    .trim());



                }

            }

        } catch (SAXParseException err) {
            System.out.println("** Parsing error" + ", line "
                    + err.getLineNumber() + ", uri " + err.getSystemId());
            System.out.println(" " + err.getMessage());

        } catch (SAXException e) {
            Exception x = e.getException();
            ((x == null) ? e : x).printStackTrace();

        } catch (Throwable t) {
            t.printStackTrace();
        }

4 个答案:

答案 0 :(得分:2)

由于XML本身已经破解,因此XML解析将失败。

假设尽管已经破坏,XML文件将始终具有该布局,您可以使用正则表达式来提取数据。

String str = "<?xml version=\"1.0\" ?>\n" +
                        "<Employee>\n" +
                        "<Name> Jack\n" +
                        "<EMPID> EMP001 <Address> 12 CA, USA</Address> \n" +
                        "</EMPID>\n" +
                        "</Name>\n" +
                        "</Employee>";
        str = str.replaceAll("\\n", "");
        Pattern p = Pattern.compile("<Name>(.+?)<EMPID>(.+?)<Address>(.+?)</Address>");
        Matcher m = p.matcher(str);
        while(m.find())
        {
            System.out.println("Name: " + m.group(1) + " EMPID: " + m.group(2) + " Address: " + m.group(3));
        }

收益率:

  

姓名:Jack EMPID:EMP001地址:12 CA,USA

这种模式的作用是什么:

  • <Name>将与Name代码匹配。
  • (.+?)会匹配<Name>标记后面的文字,但会在找到<EMPID>时停止匹配,因为由于添加了?,它不是贪婪模式在贪婪的运算符+之后(这将与模式的下一部分匹配。同样在本节中,匹配的任何内容都将放在一个可以在以后访问的组中。
  • 提取名称后,引擎将尝试匹配<EMPID>代码。
  • 之后<EMPID>标记已匹配,将执行类似于第2步的处理,匹配的内容将被放置在另一个组中。
  • 关于下一步,代码将查找<Address>
  • 最后,正则表达式会尝试提取<Address></Address>标记之间的任何字符,再次匹配的任何内容都将放在一个组中。

一旦正则表达式解析了字符串,我就会访问这些组并打印它们的值。作为额外的步骤,我将删除任何新行字符以将字符串作为一个单元格处理。

可以找到正则表达式的入门教程here

答案 1 :(得分:1)

格式不正确,但格式正确http://en.wikipedia.org/wiki/Well-formed_document,您可以使用任何解析器解析它。

答案 2 :(得分:1)

尝试在更正后解析XML。 格式良好的XML每个XML元素只有1个值,但可能有多个属性:

<employee attribute="attrvalue">value-string or xml-element, not both</employee>

因此,对XML的外观建议如下:

<?xml version="1.0" ?>
<Employee>
    <Name> Jack </Name>
    <EMPID> EMP001 </EMPID>
    <Address> 12 CA, USA</Address> 
</Employee>

编辑:但是,如果您从无法更改的源接收XML,那么基本上只剩下一个选项 - 在将XML转换为常规Java字符串后手动解析XML。

尝试使用不同的字符串方法,如substring,indexof等。 例如:

String empidStartElement = "<empid>";
String nameStartElement = "<name>";
String nameEndElement = empidStartElement;

String xml = "<employee><name>Jack<empid>emp001</empid></name></employee>";

Integer nameStartPosition = xml.indexOf(nameStartElement)+nameStartElement.length;
Integer nameEndPosition = xml.indexOf(nameEndElement);

String name = xml.substring(nameStartPosition, nameEndPosition);

答案 3 :(得分:0)

只需更改一行:

  

NodeList listOfPersons = getElementsByTagName(“NAME”);

为:

  

NodeList listOfPersons = doc.getChildNodes();

输出:

  

doc的根元素是Employee

     

姓名:杰克

     

ID:EMP001

     

地址:12 CA,USA