我有一个没有根节点的XML文件。除了手动添加一个“虚假”的根元素外,是否有任何方法可以在Java中解析XML文件?谢谢。
我有一个没有根节点的XML文件。除了手动添加一个“虚假”的根元素外,是否有任何方法可以在Java中解析XML文件?谢谢。
我觉得你可以创建一个新的InputStream实现,它包装了你要解析的那个流。这个实现会在包装流的字节之前返回开头根标签的字节,在包装流的字节之后返回结束根标签的字节。这个实现相当容易实现。
我也可能面临这个问题。遗留代码,对吧?
Ian。
编辑:你还可以查看java.io.SequenceInputStream,它允许你将流附加到另一个流上。你需要将前缀和后缀放入字节数组中,并将它们包装在ByteArrayInputStreams中,但这都是相当简单的。
您的XML文档需要一个根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>
我认为即使有任何API提供此选项,它也只会返回“XML”的第一个节点,看起来像根节点并且舍弃其余部分。
因此,答案可能是自己完成。Scanner或StringTokenizer可能会有所帮助。
也许一些HTML解析器可以帮助,它们通常不太严格。
这是我所做的:
有一个旧的java.io.SequenceInputStream
类,它非常古老,使用的是Enumeration
而不是List
或其他。
使用它,您可以在无根XML流周围添加根元素标签(在我的情况下为<div>
和</div>
)。 (由于性能和内存原因,不应通过连接字符串来执行此操作。)
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());
}
}