Ошибка десериализации объекта XML с использованием платформы SimpleXML только в Android

Хорошо, я ломал голову над этой проблемой в течение последних нескольких дней без решения (рыскание в Интернете и сообщениях StackOverflow для потенциальных решений безрезультатно), так что, возможно, кто-то еще знает, что здесь происходит.

Я пытаюсь разобрать JMDict с помощью SimpleXML, но получаю очень странные ошибки . Другая странная вещь заключается в том, что ошибки возникают только при отладке на Android (SDK 23, версия 6.0.1), а не локально на моем компьютере (в качестве модульного теста). В настоящее время я получаю 2 ошибки:

Ошибка 1

org.xmlpull.v1.XmlPullParserException: Unexpected token (position:TEXT\n@399:1 in java.io.InputStreamReader@e2fbd29)

Я знаю, что причиной этой ошибки является комментарий между объявлением DTD и корневым элементом, а также новая строка. Проходит при удалении.

<!ENTITY joc "jocular, humorous term">
<!ENTITY anat "anatomical term">
]>
<!-- JMdict created: 2016-04-26 -->
<JMdict>
<entry>

Но почему это происходит? Как я могу подавить эту ошибку? И что еще более важно, почему это происходит только тогда, когда я запускаю его в Android? (Он отлично работает в моем модульном тесте)

Ошибка 2

04-27 23:58:13.038 9527-9527/ca.fuwafuwa.kaku W/System.err: org.xmlpull.v1.XmlPullParserException: unresolved: &n; (position:ENTITY_REF null@408:9 in java.io.InputStreamReader@bc1fe42)

Ошибка, которая вызывает это, вероятно:

<entry>
    <ent_seq>1000000</ent_seq>
    <r_ele>
        <reb>ヽ</reb>
    </r_ele>
    <r_ele>
        <reb>くりかえし</reb>
    </r_ele>
    <sense>
        <pos>&n;</pos>    <------------------------------------ THIS GUY
        <gloss>repetition mark in katakana</gloss>
        <gloss xml:lang="ita">simbolo di ripetizione in katakana</gloss>
    </sense>
</entry>

За исключением того, что это определенно определено в DTD:

<!ENTITY n "noun (common) (futsuumeishi)">

Предпринятые попытки

И опять же, обе эти ошибки НЕ возникают при запуске в качестве модульного теста (на компьютере, а не на Android-устройстве/эмуляторе), и весь JMDict анализируется правильно. Вот модульный тест:

Stuff работает как модульный тест!

public class ExampleUnitTest {

    @BeforeClass
    public static void ClassSetup(){
        // Needed because there's a 64000 default limit in the JDK
        // I didn't see this limit on Android for some reason
        System.setProperty("jdk.xml.entityExpansionLimit", "0");
    }

    @Test
    public void wtfXmlSrsly() throws Exception {
        Serializer serializer = new Persister();
        File file = new File("D:\\Android\\JMDictOriginal.xml");
        JmDict dict = serializer.read(JmDict.class, file, false);
    }
}

Вот версия для Android, которая великолепно провалилась:

Не модульный тест? Ха-ха, пора терпеть неудачу!

public void parseDict() throws Exception{

    Log.d(TAG, "INITIALIZING DICTIONARY");

    long startTime = System.currentTimeMillis();

    Serializer serializer = new Persister();
    String fileLoc = mContext.getExternalFilesDir(null).getAbsolutePath();
    File file = new File(fileLoc, "JMDict.xml");

    Log.d(TAG, file.getAbsolutePath());

    JmDict dict = serializer.read(JmDict.class, file, false);

    Log.d(TAG, String.format("FINISHED, TOOK %d", System.currentTimeMillis() - startTime));
}

Насколько я могу судить, они в основном делают то же самое.

Объекты десериализации SimpleXML

@Root(name="JMdict")
public class JmDict {
    @ElementList(entry = "entry", inline = true)
    List<JmEntry> entry;
}

@Root(name="entry")
public class JmEntry {
    @Element(name = "ent_seq")
    private String ent_seq;
    @ElementList(entry = "k_ele", inline = true, required = false)
    private List<JmKEle> k_ele;
    @ElementList(entry = "r_ele", inline = true)
    private List<JmREle> r_ele;
    @Element(name = "info", required = false)
    private JmInfo info;
    @ElementList(entry = "sense", inline = true)
    private List<JmSense> sense;
}

@Root(name = "k_ele")
public class JmKEle {
    @Element(name = "keb")
    private String keb;
    @ElementList(entry = "ke_inf", inline = true, required = false)
    private List<String> ke_inf;
    @ElementList(entry = "ke_pri", inline = true, required = false)
    private List<String> ke_pri;
}

@Root(name = "r_ele")
public class JmREle {
    @Element(name = "reb")
    private String reb;
    @Element(name = "re_nokanji", required = false)
    private String re_nokanji;
    @ElementList(entry = "re_restr", inline = true, required = false)
    private List<String> re_restr;
    @ElementList(entry = "re_inf", inline = true, required = false)
    private List<String> re_inf;
    @ElementList(entry = "re_pri", inline = true, required = false)
    private List<String> re_pri;
}

@Root(name = "info")
public class JmInfo {
    @ElementList(entry = "links", inline = true, required = false)
    private List<Links> links;
    @ElementList(entry = "bibl", inline = true, required = false)
    private List<Bibl> bibl;
    @ElementList(entry = "etym", inline = true, required = false)
    private List<String> etym;
    @ElementList(entry = "audit", inline = true, required = false)
    private List<Audit> audit;
}

@Root(name = "links")
public class Links {
    @Element(name = "link_tag")
    private String link_tag;
    @Element(name = "link_desc")
    private String link_desc;
    @Element(name = "link_uri")
    private String link_uri;
}

@Root(name = "bibl")
public class Bibl {
    @Element(name = "bib_tag", required = false)
    private String bib_tag;
    @Element(name = "bib_txt", required = false)
    private String bib_txt;
}

@Root(name = "audit")
public class Audit {
    @Element(name = "upd_date")
    private String upd_date;
    @Element(name = "upd_detl")
    private String upd_detl;
}

@Root(name = "sense")
public class JmSense {
    @ElementList(entry = "stagk", inline = true, required = false)
    private List<String> stagk;
    @ElementList(entry = "stagr", inline = true, required = false)
    private List<String> stagr;
    @ElementList(entry = "pos", inline = true, required = false)
    private List<String> pos;
    @ElementList(entry = "xref", inline = true, required = false)
    private List<String> xref;
    @ElementList(entry = "ant", inline = true, required = false)
    private List<String> ant;
    @ElementList(entry = "field", inline = true, required = false)
    private List<String> field;
    @ElementList(entry = "misc", inline = true, required = false)
    private List<String> misc;
    @ElementList(entry = "s_inf", inline = true, required = false)
    private List<String> s_inf;
    @ElementList(entry = "lsource", inline = true, required = false)
    private List<String> lsource;
    @ElementList(entry = "dial", inline = true, required = false)
    private List<String> dial;
    @ElementList(entry = "gloss", inline = true, required = false)
    private List<String> gloss;
    @ElementList(entry = "example", inline = true, required = false)
    private List<String> example;
}

Альтернативы

В качестве альтернативы, если кто-то может предложить платформу для синтаксического анализа XML на Android, которая действительно работает для этого варианта использования, это тоже сработает. Он также должен обрабатывать этот случай (SimpleXML не очень хорошо с этим справляется):

<!ELEMENT gloss (#PCDATA | pri)*>
<!ELEMENT pri (#PCDATA)>
<!-- Above breaks down into: -->

<gloss>GLOSS TEXT</gloss>
<!-- or -->
<gloss><pri>PRI TEXT</pri></gloss>

Я думал, что синтаксический анализ XML уже решен. Я никогда не ожидал, что застряну на синтаксическом анализе XML на 3 дня подряд :/

Обновлять

Хорошо, я почти уверен, что сейчас что-то сломалось на Android, и он не может анализировать объекты DTD или что-то в этом роде. Я прочитал здесь, что вы должны исключить некоторые зависимости, которые по умолчанию присутствуют в Android - может там как-то поменялась реализация?

Я даже не смог разобрать этот очень простой файл XML с объявлением ENTITY:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XmlTest [
<!ELEMENT XmlTest (sometest, atest*)>
<!ELEMENT sometest (#PCDATA) >
<!ELEMENT atest (#PCDATA) >
<!ENTITY noun "noun">
]><XmlTest>
    <sometest>sometest</sometest>
    <atest>test1</atest>
    <atest>&noun;</atest>
</XmlTest>

Это привело к:

org.xmlpull.v1.XmlPullParserException: unresolved: &noun; (position:ENTITY_REF null@10:18 in java.io.InputStreamReader@4c793e1)


person 0xbad1d3a5    schedule 28.04.2016    source источник