3

XML を処理したことがないので、XML ファイル内で CDATA を処理する方法がわかりません。ノード、親、子ノード、nList などで迷っています。

これらのコードのスニペットから、私の問題が何であるかを誰か教えてもらえますか?

私のgetTagValue()方法は、CDATA を含む「詳細」を除くすべてのタグで機能します。

.....
NodeList nList = doc.getElementsByTagName("Assignment");
for (int temp = 0; temp < nList.getLength(); temp++) {
    Node nNode = nList.item(temp);
    if (nNode.getNodeType() == Node.ELEMENT_NODE) {
        Element eElement = (Element) nNode;
        results = ("Class : " + getTagValue("ClassName", eElement)) + 
                  ("Period : " + getTagValue("Period", eElement)) +
                  ("Assignment : " + getTagValue("Details", eElement));
        myAssignments.add(results);
    }
}
.....
private String getTagValue(String sTag, Element eElement) {
    NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();

    Node nValue = (Node) nlList.item(0);
    if((CharacterData)nValue instanceof CharacterData)
    {
        return ((CharacterData) nValue).getData();
    }
    return nValue.getNodeValue();
}
4

1 に答える 1

5

あなたの問題は、getTagValueメソッドの次のコード行にあると思われます。

Node nValue = (Node) nlList.item(0);

あなたは常に最初の子供を産んでいます!ただし、複数ある場合もあります。

次の例には、テキスト ノード「detail」、CDATA ノード「with cdata」、およびテキスト ノード「here」の 3 つの子があります。

<Details>detail <![CDATA[with cdata]]> here</Details>

コードを実行すると、「詳細」のみが取得され、残りは失われます。

次の例には 1 つの子があります: CDATA ノード "detail with cdata here":

<Details><![CDATA[detail with cdata here]]></Details>

コードを実行すると、すべてが得られます。

ただし、上記と同じ例を次のように記述します。

<Details>
   <![CDATA[detail with cdata here]]>
</Details>

スペースとライン フィードがテキスト ノードとして取得されるため、3 つの子を持つようになりました。コードを実行すると、改行のある最初の空のテキスト ノードが取得され、残りは失われます。

すべての子を (いくつであっても) ループし、それぞれの値を連結して完全な結果を取得するか、プレーン テキストと CDATA 内のテキストを区別することが重要でない場合はcoalescing、ドキュメントにプロパティを設定する必要があります。ビルダーファクトリーファースト:

DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setCoalescing(true);
...

Coalescing は、このコードによって作成されたパーサーが CDATA ノードを Text ノードに変換し、隣接する (存在する場合) テキスト ノードに追加することを指定します。デフォルトでは、この値は false に設定されています。

于 2012-04-07T18:07:24.750 に答える