Android 1.5 и dom4j - имена атрибутов анализируются некорректно - PullRequest
1 голос
/ 07 февраля 2011

Я работаю над приложением для Android 1.5.В настоящее время мне нужно разобрать файл XML.Поскольку Android не поддерживает XPath в API уровня 3, я решил использовать библиотеки dom4j и jaxen для чтения файла.

У меня есть простой XML-файл (test1.xml):

<?xml version="1.0" encoding="utf-8" ?>
<tests>
    <resources base_lang="en">
            <string base="example">
                    <localization lang="pl">Przykład</localization>
            </string>
    </resources>
    <test name="main name">
            <title>Main Title</title>
            <description>Long description</description>
    </test>
</tests>

И простой код:

SAXReader reader = new SAXReader();
Document doc = reader.read("file:///sdcard/tests/test1.xml");
Node node = doc.selectSingleNode("/tests/test");
Element elem = (Element)node;
for(int j=0;j<elem.attributeCount();++j) {
    Attribute attr = elem.attribute(j);
    Logger.getLogger(AutoTesterMain.class.getName()).log(Level.SEVERE, "ATTR: "+attr.getName()+"="+attr.getValue());
}

Он читает файл test1.xml, находит узел "/ tests / test" и перечисляет его атрибуты.Когда я запускаю этот код как часть «настольного» Java-приложения (я не очень разбираюсь в терминологии Java), он отображает то, что я ожидаю (OpenJDK 1.8.3 под Fedora Linux):

SEVERE: ATTR: name=main name

К сожалениюв Android 1.5 (эмулятор ofc) точно такой же код показывает:

E/AutoTesterMain(  823): ATTR: base_lang=main name

Как видите, значение атрибута в порядке, но есть проблема с именем.Я совершенно не представляю, почему в этом месте появляется имя атрибута из совершенно другого элемента DOM ("/ tests / resources").Кажется, он неправильно анализирует мой файл, поэтому я, вероятно, установил что-то неправильно ...

Конечно, обе версии используют одинаковые .jars с библиотеками dom4j и jaxen, так что это, вероятно, нормально.

Эта проблема имеет больше последствий, чем только неправильный список атрибутов.Он также не позволяет мне правильно читать атрибуты, используя XPath - выбор "/ tests / test / @ name" ничего не дает, а "/ tests / test / @ base_lang" дает мне строку "main name".Это, очевидно, вызвано той же ошибкой, что и в приведенном выше списке атрибутов.

Кто-нибудь сталкивался с этим?Как я могу это исправить?

Переход на более новый Android с собственной поддержкой XPath, к сожалению, не вариант для меня.

Я пытался найти что-нибудь в Интернете и здесь, но безуспешно.

1 Ответ

1 голос
/ 18 марта 2011

У меня та же проблема при запуске моего приложения на эмуляторе Android 2.1. Хотя для 2.2 работает отлично. Используемая мной версия dom4j lib v1.6.

Как видно из следующего извлечения, все имена атрибутов заменены на имя первого атрибута в моем XML-файле:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd"><ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
    <head>
        <meta version="dtb:uid" version="6efac3c8-0d51-46bd-b125-58dae01bf92e"/>
        <meta version="dtb:depth" version="4"/>
        <meta version="dtb:totalPageCount" version="0"/>
        <meta version="dtb:maxPageNumber" version="0"/>
    </head>
    <docTitle>
        <text>Book</text>
    </docTitle>
    <navMap>
        <navPoint version="navPoint-1" version="1">
            <navLabel>
                <text>Header1</text>
            </navLabel>
            <content version="Text/Section0001.xhtml"/>
            <navPoint version="navPoint-2" version="2">

Когда фактический xml равен:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN"
   "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">

<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
    <head>
        <meta name="dtb:uid" content="6efac3c8-0d51-46bd-b125-58dae01bf92e"/>
        <meta name="dtb:depth" content="4"/>
        <meta name="dtb:totalPageCount" content="0"/>
        <meta name="dtb:maxPageNumber" content="0"/>
    </head>
    <docTitle>
        <text>Book</text>
    </docTitle>
    <navMap>
        <navPoint id="navPoint-1" playOrder="1">
            <navLabel>
                <text>Header1</text>
            </navLabel>
            <content src="Text/Section0001.xhtml"/>
            <navPoint id="navPoint-2" playOrder="2">

Кажется, что XML-документ анализируется неправильно. Вот мой исходный код:

inputStream = new FileInputStream(ncfPath);
SAXReader reader = new SAXReader(); // dom4j SAXReader
Document document = reader.read(inputStream);
String xml = document.asXML();

Дайте мне знать, если вы нашли решение этой проблемы.

РЕДАКТИРОВАТЬ: та же проблема для DOM4J 2.0 альфа 2 EDIT2: наконец-то я нашел решение. Проблема действительно в исходном коде dom4j. Вот ссылка на проблему, записанную почти два года (!) Назад. Чтобы исправить это, вам нужно исправить следующий метод в \ dom4j-1.6.1 \ src \ java \ org \ dom4j \ tree \ NamespaceStack.java :

public QName getAttributeQName(String namespaceURI, String localName, String qualifiedName) {
    // Fix: qualifiedName is empty on Android 2.1
    // refer to https://sourceforge.net/tracker/index.php?func=detail&aid=2789052&group_id=16035&atid=116035#
        if (qualifiedName == null || qualifiedName.length() == 0) {
            qualifiedName = localName;
        }
...