0

Android 環境で一部の XML ファイルの解析に問題があります... Android アプリを起動した後、JAVA 環境で XML を解析するテストを行いました。

だから、私はこのコードを書きました:

private void addMeta(Node n){
    String[] fields = {"src", "timestamp", "title", "kind", "ref", "crcData"};
    Element e = (Element)n.getChildNodes();
    //... more code
}

しかし、これを Android で使用すると、ClassCastException が返されます。

問題を見つけるために調べていましたが、(理解できるように)問題は次のとおりです。

Android は、別の種類の「NodeList」(「n.getChildNodes()」によって返されるデータ型)を取得しています。Android が取得しているデータ型は、org.apache.harmony.xml.dom.NodeListImpl です。

それで、それを見て、コードを直接キャストからメソッドに変更しました。コードは次のとおりです。

private org.w3c.dom.Element getElements(Node n){
    org.w3c.dom.NodeList nl = (org.w3c.dom.NodeList)n.getChildNodes();
    return (org.w3c.dom.Element)nl;
}

次に、「Element e = (Element)n.getChildNodes()」を「org.w3c.dom.Element e = this.getElements(n)」に変更します。

しかし、「getElements」メソッドの内部で、奇妙なことが起こります...

「nl」は引き続き「org.apache.harmony.xml.dom.NodeListImpl」として取得されるため、ClassCastException が引き続き発生します。

それで、「org.apache ...」NodeListの代わりに「org.w3c.dom.NodeList」を取得する必要があるかもしれませんか?

ありがとう、そして私の下手な英語でごめんなさい... :s

4

2 に答える 2

0

ご回答ありがとうございます。

しかし、XML を解析するときは、常に子を持つノードを取得するように注意しています (そのため、getChildNodes は常に NodeList を返します)。

「addMeta」を呼び出す前に、いくつかの関数を使用してノードを反復処理します。

開始点は「塗りつぶし」メソッドです。

public boolean fill(String[] curr, String file){
    try{
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new java.io.StringReader(file)));

        doc.getDocumentElement().normalize();

        for(int i=0;i<curr.length;i++)
            this.treat((doc.getElementsByTagName(curr[i])), curr[i]);
    }catch(ParserConfigurationException e){
        this.error = Strings.PARSEEXCEPTION.getValue();
        this.exception = e;
        return false;
    }catch(SAXException e){
        this.error = Strings.SAXEXCEPTION.getValue();
        this.exception = e;
        return false;
    }catch(IOException e){
        this.error = Strings.IOEXCEPTION.getValue();
        this.exception = e;
        return false;
    }

    return this.check();
}

次に、「治療」方法:

private void treat(NodeList nl, String kind){
    for(int i=0;i<nl.getLength();i++)
        this.add(nl.item(i), kind);
}

「追加」方法:

private void add(Node n, String kind){
    if(kind.equals("meta"))
        this.addMeta(n);
            //... more code

そして、「addMeta」では、取得しようとしているすべてのアイテムに子があります。解析しようとしている XML の基本構造:

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="myweb/myxmlns.xsd">
<meta>
    <generator>
        <src>62.83.204.127</src>
        <timestamp>1359743849</timestamp>
    </generator>
    <doc>
        <title>Title</title>
        <kind>m</kind>
    </doc>
    <ext>
        <authUser>
            <ref>David-Solé-González-1</ref>
        </authUser>
    </ext>
    <crcData>2e021a71461e5a1bf6b71a5779446857a1d6b073</crcData>
</meta>
</Document>

そして、もちろんJavaではうまく動作しますが、Android では ClassCastException が発生しています...

于 2013-07-17T05:12:25.963 に答える
0

NodeList は 0 個以上のノードを指しているため、ノード/要素に直接キャストすることはできません。構造に応じて、子にはノードの要素と属性が含まれる場合があります。

NodeList から特定のノードに到達するには、それを反復処理する必要があります。

for (int i = 0; i < nodeList.getLength(); i++) {
   Node item = nodeList.item(i);
   // if this matches the element name you're 
   // looking for then return else continue
}

もう 1 つのオプションは、指定された Node が要素であるかどうかを確認し、getElementsByTagName("name") を使用してクエリを実行し、それを反復処理して正しいものを見つけて返すことです。

if (node.getNodeType() == Node.ELEMENT_NODE) {
   Element e = (Element) node;
   NodeList elements = e.getElementsByTagName("name_of_tag_you_want");
   // process node list and find the right one and return

}
于 2013-07-16T20:31:10.177 に答える