Разбор XML-файла без рута в Java - PullRequest
4 голосов
/ 07 июля 2010

У меня есть этот XML-файл, у которого нет корневого узла.Кроме ручного добавления «поддельного» корневого элемента, есть ли способ проанализировать XML-файл в Java?Спасибо.

Ответы [ 6 ]

5 голосов
/ 07 июля 2010

Полагаю, вы могли бы создать новую реализацию InputStream, которая обернет ту, с которой вы будете анализировать.Эта реализация будет возвращать байты открывающего корневого тега до байтов из упакованного потока и байты закрывающего корневого тега впоследствии.Это было бы довольно просто сделать.

Я тоже могу столкнуться с этой проблемой.Устаревший код, а?

Ян.

Редактировать: Вы также можете посмотреть на java.io.SequenceInputStream, который позволяет вам добавлять потоки друг к другу.Вам нужно будет поместить свой префикс и суффикс в байтовые массивы и обернуть их в ByteArrayInputStreams, но все это довольно просто.

4 голосов
/ 07 июля 2010

Ваш XML-документ нуждается в корневом элементе xml, чтобы считаться правильно сформированным .Без этого вы не сможете проанализировать его с помощью парсера xml.

3 голосов
/ 07 июля 2010

Один из способов - создать собственную фиктивную оболочку, не касаясь оригинального «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>
1 голос
/ 20 января 2012

Вы можете использовать другой анализатор, например Jsoup . Может анализировать XML без рута.

0 голосов
/ 30 июля 2018

Вот что я сделал:

Существует старый класс java.io.SequenceInputStream, который настолько стар, что требует Enumeration, а не List или что-то подобное.

С его помощью вы можете добавлять и добавлять теги корневых элементов (<div> и </div> в моем случае) вокруг вашего потока XML без полномочий root. (Вы не должны делать это путем объединения строк из-за производительности и памяти.)

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());
    }
}
0 голосов
/ 07 июля 2010

Я думаю, что даже если какой-либо API будет иметь опцию для этого, он вернет вам только первый узел «XML», который будет выглядеть как корень, и отбросит остальные.

Так что ответ, вероятно, сделать это самостоятельно. Сканер или StringTokenizer могут сделать свое дело.

Может быть, некоторые html-парсеры могут помочь, обычно они менее строгие.

...