Объедините два XML-файла в Java

Я знаю, что это не тот ответ, который вы ожидаете, но чтение документа поможет; -).

Полная документация доступна по адресу:

https://mechanicalsoup.readthedocs.io/

Возможно, вы захотите начать с урока:

https://mechanicalsoup.readthedocs.io/en/stable/tutorial.html

Короче говоря, вам нужно выбрать форму, которую вы хотите заполнить: [119 ]

browser.select_form('form[action="/post"]')

Тогда заполнение полей так же просто, как

browser["custname"] = "Me"
browser["custtel"] = "00 00 0001"
browser["custemail"] = "nobody@example.com"
browser["comments"] = "This pizza looks really good :-)"

13
задан Mark Davidson 30 March 2009 в 19:22
поделиться

9 ответов

Не очень изящный, но Вы могли сделать это с синтаксическим анализатором DOM и XPath:

public class MergeXmlDemo {

  public static void main(String[] args) throws Exception {
    // proper error/exception handling omitted for brevity
    File file1 = new File("merge1.xml");
    File file2 = new File("merge2.xml");
    Document doc = merge("/run/host/results", file1, file2);
    print(doc);
  }

  private static Document merge(String expression,
      File... files) throws Exception {
    XPathFactory xPathFactory = XPathFactory.newInstance();
    XPath xpath = xPathFactory.newXPath();
    XPathExpression compiledExpression = xpath
        .compile(expression);
    return merge(compiledExpression, files);
  }

  private static Document merge(XPathExpression expression,
      File... files) throws Exception {
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
        .newInstance();
    docBuilderFactory
        .setIgnoringElementContentWhitespace(true);
    DocumentBuilder docBuilder = docBuilderFactory
        .newDocumentBuilder();
    Document base = docBuilder.parse(files[0]);

    Node results = (Node) expression.evaluate(base,
        XPathConstants.NODE);
    if (results == null) {
      throw new IOException(files[0]
          + ": expression does not evaluate to node");
    }

    for (int i = 1; i < files.length; i++) {
      Document merge = docBuilder.parse(files[i]);
      Node nextResults = (Node) expression.evaluate(merge,
          XPathConstants.NODE);
      while (nextResults.hasChildNodes()) {
        Node kid = nextResults.getFirstChild();
        nextResults.removeChild(kid);
        kid = base.importNode(kid, true);
        results.appendChild(kid);
      }
    }

    return base;
  }

  private static void print(Document doc) throws Exception {
    TransformerFactory transformerFactory = TransformerFactory
        .newInstance();
    Transformer transformer = transformerFactory
        .newTransformer();
    DOMSource source = new DOMSource(doc);
    Result result = new StreamResult(System.out);
    transformer.transform(source, result);
  }

}

Это предполагает, что можно держать по крайней мере два из документов в RAM одновременно.

11
ответ дан 1 December 2019 в 23:16
поделиться

Могло бы помочь, были ли Вы явными о результате, что Вы интересуетесь достижением. Это то, что Вы просите?

Документ A:

<root>
  <a/>
  <b>
    <c/>
  </b>
</root>

Документ B:

<root>
  <d/>
</root>

Объединенный результат:

<root>
  <a/>
  <b>
    <c/>
  </b>
  <d/>
</root>

Вы волнуетесь по поводу масштабирования для больших документов?

Самый легкий способ реализовать это в Java состоит в том, чтобы использовать потоковую передачу синтаксический анализатор XML (Google для 'java StAX'). Если Вы будете пользоваться javax.xml.stream библиотекой, то Вы найдете, что XMLEventWriter имеет удобный метод XMLEventWriter#add (XMLEvent). Все, что необходимо сделать, является циклом по высокоуровневым элементам в каждом документе, и добавьте их к устройству записи, использующему этот метод для генерации объединенного результата. Единственная броская часть реализует логику читателя, которая только рассматривает (только вызовы 'добавляют') на высокоуровневых узлах.

Я недавно реализовал этот метод, если Вам нужны подсказки.

2
ответ дан 1 December 2019 в 23:16
поделиться

Я смотрел на ссылку, на которую ссылаются; это нечетно, что XMLMerge не работал бы как ожидалось. Ваш пример кажется простым. Вы читали раздел, наделенный правом Используя объявления XPath с XmlMerge? Используя пример, попытайтесь настроить XPath для результатов и установить его для слияния. Если бы я читаю документ правильно, он выглядел бы примерно так:

XPath.resultsNode=results
action.resultsNode=MERGE
1
ответ дан 1 December 2019 в 23:16
поделиться

Вы смогли писать приложение Java что deserilizes XML-документы в объекты, затем "объединять" отдельные объекты программно в набор. Можно затем сериализировать объект коллекции, отступают к XML-файлу со всем "объединенным".

API JAXB имеет некоторые инструменты, которые могут преобразовать XML-документ / схема в классы Java. "xjc" инструмент смог делать это, хотя я не могу помнить, можно ли создать классы непосредственно из документа XML, или если необходимо генерировать схему сначала. Существуют инструменты там, чем может генерировать схему из документа XML.

Надеюсь, это поможет... не уверенный, если это - то, что Вы искали.

0
ответ дан 1 December 2019 в 23:16
поделиться

В дополнение к использованию Stax (который действительно имеет смысл), это, вероятно, было бы легче с StaxMate (http://staxmate.codehaus.org/Tutorial). Просто создайте 2 SMInputCursors и дочерний курсор в случае необходимости. И затем типичная сортировка слиянием с 2 курсорами. Подобный пересечению документов DOM способом рекурсивного спуска.

0
ответ дан 1 December 2019 в 23:16
поделиться

Можно попробовать Dom4J, который обеспечивает очень хорошее средство извлечь информацию с помощью Запросов XPath и также позволяет Вам писать XML очень легко. Просто необходимо играть вокруг с API некоторое время, чтобы сделать задание

0
ответ дан 1 December 2019 в 23:16
поделиться

Вы рассмотрели просто не беспокойство парсингом XML "правильно" и просто обработкой файлов как большие длинные строки и использование скучных старых вещей, таких как карты хеша и регулярные выражения...? Это могло быть одним из тех случаев, где необычные акронимы с X в них просто делают задание более трудным, чем это должно быть.

Очевидно, это действительно зависит немного от того, сколько данных на самом деле необходимо проанализировать при выполнении слияния. Но звуком вещей, ответ на это не очень.

-6
ответ дан 1 December 2019 в 23:16
поделиться

Так, Вы только интересуетесь слиянием элементов 'результатов'? Все остальное проигнорировано? То, что input0 имеет <информационный тип =/> и input1, имеет <информационный тип = "b"/> и ожидаемый результат имеет <информационный тип =/>, кажется, предлагает это.

Если бы Вы не волнуетесь по поводу масштабирования, и Вы хотите решить эту проблему быстро затем, я предложил бы писать определенный для проблемы бит кода, который пользуется простой библиотекой как JDOM, чтобы рассмотреть исходные данные и записать выходной результат.

Попытка записать универсальный инструмент, который был достаточно 'умен' для обработки всех возможных случаев слияния, будет довольно трудоемкой - необходимо было бы выставить поддержку конфигурации определить правила слияния. Если Вы знаете точно, на что Ваши данные собираются быть похожими, и Вы знаете точно, как слияние должно быть выполнено затем, я предположил бы, что Ваш алгоритм обойдет каждый вход XML и запишет в единственный вывод XML.

0
ответ дан 1 December 2019 в 23:16
поделиться

Спасибо всем за их предложения, к сожалению, ни один из предложенных методов не оказался подходящим, так как мне нужно было иметь правила для того, чтобы различные узлы структуры были объединены.

Итак, я взял DTD, относящийся к XML-файлам, которые я объединял, и на его основе создал ряд классов, отражающих структуру. Исходя из этого, я использовал XStream для десериализации XML-файла обратно в классы.

Таким образом, я аннотировал свои классы, превращая его в процесс использования комбинации правил, назначенных аннотациями, и некоторого отражения для объединения Объекты в отличие от объединения фактической структуры XML.

Если кого-то интересует код, который в данном случае объединяет файлы XML Nmap, см. http://fluxnetworks.co.uk/NmapXMLMerge.tar.gz коды не идеальны, и я признаю, что они не очень гибкие, но это определенно работает. Я планирую заново реализовать систему, автоматически анализируя DTD, когда у меня будет свободное время.

3
ответ дан 1 December 2019 в 23:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: