【问题标题】:Parsing an XML file without root in Java在 Java 中解析没有 root 的 XML 文件
【发布时间】:2010-07-07 02:41:52
【问题描述】:

我有这个没有根节点的 XML 文件。除了手动添加“假”根元素之外,还有什么方法可以解析 Java 中的 XML 文件?谢谢。

【问题讨论】:

  • 如果它没有根节点,它就不是一个真正的 XML 文件。由于某种原因,添加“虚拟”根节点不是一种选择,还是您只是对替代方案感兴趣?
  • Anon,谢谢您的回复,我想我正在寻找更优雅的东西。我知道这很讽刺,我正在寻找一个优雅的解决方案来解决问题。不过,只是想知道是否还有其他选择。
  • 我真的希望,没有这样的选择。为什么?因为像这样“宽松”的标准合规性根本无助于这些标准的执行。而且,希望有更多的人不想处理像非格式良好的 xml 这样的临时本土“标准”,而不是愿意处理的人。
  • 即使您可以正确解析它,您希望输出什么?顶级元素的一系列文档节点?这仍然很杂乱无章。这与只是将其包裹起来并自己将它们拉下来真的没有什么不同。

标签: java xml parsing xml-parsing


【解决方案1】:

我想你可以创建一个新的 InputStream 实现,它包装你将要解析的那个。此实现将在来自包装流的字节之前返回开始根标记的字节,然后返回结束根标记的字节。这样做相当简单。

我也可能面临这个问题。遗留代码,嗯?

伊恩。

编辑:您还可以查看 java.io.SequenceInputStream ,它允许您将流彼此附加。您需要将前缀和后缀放入字节数组中,然后将它们包装在 ByteArrayInputStreams 中,但这一切都相当简单。

【讨论】:

【解决方案2】:

您的 XML 文档需要一个根 xml 元素才能被视为 well formed。如果没有这个,您将无法使用 xml 解析器对其进行解析。

【讨论】:

  • 感谢克罗克,感谢您的回复。我知道 XML 格式良好的规则。但是,我正在处理一个糟糕的遗留场景,这就是我必须处理的问题,所以这就是为什么要寻找选择。谢谢。
【解决方案3】:

一种方法是提供您自己的虚拟包装器,而无需触及原始的“xml”(格式不正确的“xml”)需要这个词:

语法

<!DOCTYPE some_root_elem SYSTEM "/home/ego/some.dtd"
[
  <!ENTITY entity-name "Some value to be inserted at the entity">
]

示例:

<!DOCTYPE dummy [
<!ENTITY data SYSTEM "http://wherever-my-data-is">
]>
<dummy>
&data;
</dummy>

【讨论】:

  • 这仍然是围绕 XML 包装的东西。我正在寻找的是Java中是否有某种方法可以通过在某些API中设置一些属性来解析这个XML。
  • 您可以将外部包装器放在程序内部的字符串中;它实际上不需要存在于文件系统中。
【解决方案4】:

您可以使用另一个解析器,例如 Jsoup。它可以在没有根的情况下解析 XML。

【讨论】:

    【解决方案5】:

    我认为,即使任何 API 都有此选项,它也只会返回“XML”的第一个节点,该节点看起来像一个根节点并丢弃其余节点。

    所以答案可能是自己做。 Scanner 或 StringTokenizer 可能会成功。

    也许一些 html 解析器可能会有所帮助,它们通常不那么严格。

    【讨论】:

      【解决方案6】:

      这就是我所做的:

      有一个旧的java.io.SequenceInputStream 类,它太旧了,它需要Enumeration 而不是List 之类的。

      有了它,您可以在无根 XML 流周围添加和附加根元素标签(在我的例子中为 &lt;div&gt;&lt;/div&gt;)。 (由于性能和内存原因,您不应该通过连接字符串来做到这一点。)

      public void tryExtractHighestHeader(ParserContext context)
      {
          String xhtmlString = context.getBody();
          if (xhtmlString == null || "".equals(xhtmlString))
              return;
      
          // The XHTML needs to be wrapped, because it has no root element.
          ByteArrayInputStream divStart = new ByteArrayInputStream("<div>".getBytes(StandardCharsets.UTF_8));
          ByteArrayInputStream divEnd = new ByteArrayInputStream("</div>".getBytes(StandardCharsets.UTF_8));
          ByteArrayInputStream is = new ByteArrayInputStream(xhtmlString.getBytes(StandardCharsets.UTF_8));
          Enumeration<InputStream> streams = new IteratorEnumeration(Arrays.asList(new InputStream[]{divStart, is, divEnd}).iterator());
      
          try (SequenceInputStream wrapped = new SequenceInputStream(streams);) {
              DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
              DocumentBuilder builder = builderFactory.newDocumentBuilder();
              Document xmlDocument = builder.parse(wrapped);
      

      从这里你可以做任何你喜欢的事情,但请记住额外的元素。

              XPath xPath = XPathFactory.newInstance().newXPath();
          }
          catch (Exception e) {
              throw new RuntimeException("Failed parsing XML: " + e.getMessage());
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-07-16
        • 1970-01-01
        • 1970-01-01
        • 2011-08-11
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 2015-08-12
        • 1970-01-01
        相关资源
        最近更新 更多