2012-04-06 8 views
3

Я до этого никогда не обрабатывал XML, поэтому я не уверен, как обрабатывать CDATA внутри XML-файла. Я теряюсь в узлах, родителях, дочерних узлах, nList и т. Д.Обработка CDATA из XML через DOM-парсер

Может ли кто-нибудь сказать мне, что моя проблема из этих фрагментов кода?

Мой метод 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(); 
} 
+0

Помимо превосходного объяснения Богдана, если вы можете использовать Хом, dOM4J и т.д., вы, вероятно, будет лучше для него. –

ответ

5

Я подозревал, что ваша проблема в следующей строке коды из метода getTagValue:

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

Вы всегда получаете первый ребенок! Но у вас может быть несколько.

Следующий пример имеет 3 детей: текстовый узел «деталь», CDATA узел «с CDATA» и текстовый узел «здесь»:

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

Если запустить свой код, вы получите только «деталь», вы освобождаете остальных.

Следующий пример имеет 1 ребенка: в CDATA узел «подробно с CDATA здесь»:

<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 specifies that the parser produced by this code will convert CDATA nodes to Text nodes and append it to the adjacent (if any) text node. By default the value of this is set to false.

+0

просто искал то же самое в js, поэтому 'element.childNodes [0] .nodeValue' вместо' element.nodeValue' сделал трюк для меня, спасибо! –