【问题标题】:Parsing XML in Java在 Java 中解析 XML
【发布时间】:2014-01-10 12:50:16
【问题描述】:

我得到了这个格式不正确的 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();
        }

【问题讨论】:

  • 你没有有效的 XML,所以我认为你不能使用标准的 Java XML 解析器来解析它
  • 无法解析无格式的 XML 文件。以上 XML 格式不正确。纠正它。 Java API 会处理它。不要再编写另一个 Java API 来读取不正确的 XML。
  • “所有解析选项”是什么意思?你能解释一下你的问题吗?
  • 当您尝试解析它时遇到什么错误?我不同意这是非法的 XML。
  • 但问题不在于格式,所以它必须与您的代码有关。你能发布你用来解析它的代码吗?

标签: java xml parsing xml-parsing


【解决方案1】:

既然是 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

这个模式有什么作用:

  • &lt;Name&gt; 将匹配 Name 标记。
  • (.+?) 将匹配 &lt;Name&gt; 标记之后的文本,但在找到 &lt;EMPID&gt; 时将停止匹配,因为它不是贪婪模式,因为在贪婪运算符 + 之后添加了 ?(这将是由模式的下一部分匹配。同样在此部分中,任何匹配的内容都将放在一个组中,以便以后访问。
  • 提取名称后,引擎将尝试匹配&lt;EMPID&gt; 标记。
  • &lt;EMPID&gt;标签匹配后,会进行类似于步骤2的过程,匹配的内容将被放置在另一个组中。
  • 至于下一步,代码将寻找&lt;Address&gt;
  • 最后,正则表达式将尝试提取位于 &lt;Address&gt;&lt;/Address&gt; 标记之间的任何字符,并且再次将匹配的任何字符放入一个组中。

一旦正则表达式解析字符串,我将访问组并打印它们的值。作为一个额外的步骤,我将删除所有换行符以将字符串作为单行处理。

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

【讨论】:

  • 如何获得对模式的命令?您能建议一些学习链接或任何书籍吗?
  • @AmitG:我已经改进了我的答案,希望它能对此事有更多的了解。
  • @npinti 这个答案现在给了我很大的希望。谢谢。现在我需要将该 XML 转换为像“str”这样的字符串格式
  • @user1432151:str 的初始格式是我的 IDE (Netbeans) 在我将其从该站点复制/粘贴到 IDE 时对其进行格式化的方式。我还删除了任何换行符,因此基本上该字符串将是一长行。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 我知道这一点,但正如我上面所说,我是从服务器获取的,我无法更改。请建议我在我的情况下您知道的任何其他选项
    【解决方案4】:

    只需换行:

    NodeList listOfPersons = getElementsByTagName("NAME");

    到:

    NodeList listOfPersons = doc.getChildNodes();

    输出:

    文档的根元素是 Employee

    姓名:杰克

    ID : EMP001

    地址:美国加利福尼亚州 12 号

    【讨论】:

      猜你喜欢
      • 2016-10-31
      • 1970-01-01
      • 2012-08-26
      • 2012-11-17
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-14
      相关资源
      最近更新 更多