代码之家  ›  专栏  ›  技术社区  ›  HalfBrian

在Java中解析包含XML片段的文件

  •  2
  • HalfBrian  · 技术社区  · 14 年前

    <XmlCreated> <Product> )因此,当我尝试解析文件时,我(预期地)得到一个关于格式不正确的文档的错误。

    XmlCreated Product 标签。

    <?xml version="1.0"?>
    
    <XmlCreated>May 11 2009</XmlCreated>
    
    <!-- License Key file Attributes -->
    <Product image ="LicenseKeyFile">
    
     <!-- MyCompany -->
     <Manufacturer ID="7f">
      <SerialNumber>21072832521007</SerialNumber>
      <ChassisId>72060034465DE1C3</ChassisId>
      <RtspMaxUsers>500</RtspMaxUsers>
      <MaxChannels>8</MaxChannels>
     </Manufacturer>
    
    </Product>
    

    下面是我用来尝试加载XML的当前代码。它不起作用,但我以前用它作为格式良好的XML的起点。

    public static void main(String[] args) {
        try {
            File file = new File("C:\\path\\LicenseFile.xml");
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    db.parse(file)

    [Fatal Error] LicenseFile.xml:6:2: The markup in the document following the root element must be well-formed.
    org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed.
     at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
     at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
     at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
     at com.mycompany.licensesigning.LicenseSigner.main(LicenseSigner.java:20)
    

    我该如何解析这个令人沮丧的文件?

    5 回复  |  直到 13 年前
        1
  •  2
  •   Tyler    14 年前

    如果你知道这份文件总是格式不好。。。就这样吧。添加新虚拟对象 <root> <?xml...> </root> 在最后一个数据之后。

        2
  •  1
  •   Jherico    14 年前

    您将需要创建两个单独的文档对象,方法是将文件分解为更小的部分并分别解析这些部分(或者通过添加一个包含这两个部分的标记将它们重构为一个更大的文档)。

    <Product </Product> 然后使用这些标记创建一个可以传递到文档生成器的字符串。

        3
  •  0
  •   Jim Garrison    14 年前

    DocumentBuilder.parse() ?

    DocumentBuilder.parse(new InputSource(new StringReader(string)))
    
        4
  •  0
  •   MeBigFatGuy    14 年前

    我可能会创建一个SequenceInputStream,在其中您将真实流与两个ByteArrayInputStreams夹在一起,这两个ByteArrayInputStreams返回一些伪根开始标记和结束标记。

        5
  •  0
  •   user389981    14 年前

    在某种程度上,我同意Jim Garrison的观点,使用InputStream或StreamReader并将输入打包到所需的标记中,这是一种简单易行的方法。我可以预见的主要问题是,您必须对有效和无效的格式进行一些检查(如果您希望能够对有效和无效数据都使用该方法),如果格式无效(因为缺少根级别的标记),请用标记包装输入,如果其有效,则不要包装输入。如果输入因其他原因无效,也可以更改输入以更正格式问题。

    另外,最好将ipnut存储在字符串集合(某种类型)中,而不是字符串本身,这意味着您对输入大小没有太多限制。将文件中的每个字符串设为一行。您应该最终得到一个逻辑性和易于遵循的结构,这将使将来更容易更正其他格式问题。

    最困难的部分是找出是什么导致了无效的格式。在您的情况下,只需检查根级别的标记,如果标记存在并且格式正确,不要包装,如果没有,包装。