лучший анализатор XML Java для управления / редактирования существующего документа XML - PullRequest
6 голосов
/ 26 марта 2010

ЗАДАЧА: У меня есть существующий документ XML (UTF-8), который использует пространства имен XML и схему XML. Мне нужно проанализировать определенный элемент, добавить содержимое (которое также должно использовать префиксы пространства имен xml) к этому элементу, а затем снова выписать документ.

Какая библиотека XML-анализатора лучше всего подходит для этой ЗАДАЧИ?

Я видел предыдущий поток ( Лучший синтаксический анализатор XML для Java ), но не был уверен, подходит ли dom4j или JDOM для пространств имен / xmlSchema и хорошая поддержка символов UTF-8.

Некоторые парсеры, которые кажутся заданием для
JDOM
dOM4J
XOM
Вудсток

Есть идеи, какая из них лучшая? :-) Я использую JDK 6 и предпочитаю НЕ использовать встроенные средства SAX / DOM для выполнения этой работы, потому что это требует от меня написания слишком большого количества кода.

Помогло бы привести несколько примеров выполнения такой задачи.

Ответы [ 4 ]

6 голосов
/ 26 марта 2010

Используйте XSLT. Шутки в сторону. Это идеальная работа для этого. Просто используйте шаблон копирования, чтобы скопировать все как есть, за исключением места, где вам нужно добавить больше XML. Вы даже можете добавить XML, фактически написав XML вместо манипулирования DOM.

Это шаблон копирования:

<xsl:template match="node() | @*">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

Я знаю, что многие люди ненавидят XSLT, но это задача, в которой он действительно блестит и почти не берет кода. Кроме того, вы можете просто использовать то, что в JDK.

5 голосов
/ 26 марта 2010

Использование JDOM, взятие InputStream и превращение его в документ:

InputStream inputStream = (InputStream)httpURLConnection.getContent();
DocumentBuilderFactory docbf = DocumentBuilderFactory.newInstance();
docbf.setNamespaceAware(true);
DocumentBuilder docbuilder = docbf.newDocumentBuilder();
Document document = docbuilder.parse(inputStream, baseUrl);

В этот момент у вас есть XML в объекте Java. Готово. Легко.

Вы можете либо использовать объект документа и API Java, чтобы просто пройтись по нему, либо также использовать XPath, который я нахожу проще (как только я его изучил).

Создайте объект XPath, который занимает немного:

public static XPath buildXPath() {
    XPathFactory factory = XPathFactory.newInstance();
    XPath xpath = factory.newXPath();
    xpath.setNamespaceContext(new AtomNamespaceContext());
    return xpath;
}


public class AtomNamespaceContext implements NamespaceContext {

    public String getNamespaceURI(String prefix) {
        if (prefix == null)
            throw new NullPointerException("Null prefix");
        else if ("a".equals(prefix))
            return "http://www.w3.org/2005/Atom";
        else if ("app".equals(prefix))
            return "http://www.w3.org/2007/app";
        else if ("os".equals(prefix))
            return "http://a9.com/-/spec/opensearch/1.1/";
        else if ("x".equals(prefix)) 
            return "http://www.w3.org/1999/xhtml";
        else if ("xml".equals(prefix))
            return XMLConstants.XML_NS_URI;
        return XMLConstants.NULL_NS_URI;
    }

    // This method isn't necessary for XPath processing.
    public String getPrefix(String uri) {
        throw new UnsupportedOperationException();
    }

    // This method isn't necessary for XPath processing either.
    public Iterator getPrefixes(String uri) {
        throw new UnsupportedOperationException();
    }
}

Тогда просто используйте его, что (к счастью) совсем не занимает много времени:

return Integer.parseInt(xpath.evaluate("/a:feed/os:totalResults/text()", document));
2 голосов
/ 16 августа 2011

Поскольку основная проблема для вас - написание слишком большого количества кода, вы можете рассмотреть jOOX:

http://code.google.com/p/joox/

Я создал jOOX в качестве порта jQuery для Java. Базовая технология - это стандартный DOM Java. Пример кода:

// Find the order at index for and add an element "paid"
$(document).find("orders").children().eq(4)
           .append("<paid>true</paid>");

// Find those orders that are paid and flag them as "settled"
$(document).find("orders").children().find("paid")
           .after("<settled>true</settled>");

// Add a complex element
$(document).find("orders").append(
  $("order", $("date", "2011-08-14"),
             $("amount", "155"),
             $("paid", "false"),
             $("settled", "false")).attr("id", "13");

Примечание. Пространства имен еще явно не поддерживаются, но вы можете обойти это

1 голос
/ 26 марта 2010

Похоже, вы можете написать таблицу стилей xslt, чтобы делать то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...