在Java中读取CDATA XML

14

我正在尝试解析XML中的CDATA类型。代码运行良好,它将在控制台中打印“Links:”(大约50次,因为我有这么多链接),但链接不会出现...只是一个空白的控制台空间。我可能错过了什么?

package Parse;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLParse {
  public static void main(String[] args) throws Exception {
    File file = new File("c:test/returnfeed.xml");
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document doc = builder.parse(file);

    NodeList nodes = doc.getElementsByTagName("video");
    for (int i = 0; i < nodes.getLength(); i++) {
      Element element = (Element) nodes.item(i);
      NodeList title = element.getElementsByTagName("videoURL");
      Element line = (Element) title.item(0);
      System.out.println("Links: " + getCharacterDataFromElement(line));
    }
  }
  public static String getCharacterDataFromElement(Element e) {
    Node child = e.getFirstChild();
    if (child instanceof CharacterData) {
      CharacterData cd = (CharacterData) child;
      return cd.getData();
    }
    return "";
  }
}

结果:

Links: 

Links: 

Links: 

Links: 

Links: 

Links: 

Links: 

示例XML:(不完整文档)

<?xml version="1.0" ?> 
<response xmlns:uma="http://websiteremoved.com/" version="1.0">

    <timestamp>
        <![CDATA[  July 18, 2012 5:52:33 PM PDT 
          ]]> 
    </timestamp>
    <resultsOffset>
        <![CDATA[  0 
          ]]> 
    </resultsOffset>
    <status>
        <![CDATA[  success 
        ]]> 
    </status>
    <resultsLimit>
        <![CDATA[  207 
        ]]> 
    </resultsLimit>
    <resultsCount>
        <![CDATA[  207 
        ]]> 
    </resultsCount>
    <videoCollection>
        <name>
            <![CDATA[  Video API 
            ]]> 
        </name>
        <count>
            <![CDATA[  207 
            ]]> 
        </count>
        <description>
            <![CDATA[  
            ]]> 
        </description>
        <videos>
            <video>
                <id>
                    <![CDATA[  8177840 
                    ]]> 
                </id>
                <headline>
                    <![CDATA[  Test1
                    ]]> 
                </headline>
                <shortHeadline>
                    <![CDATA[  Test2
                    ]]> 
                </shortHeadline>
                <description>
                    <![CDATA[ Test3

                    ]]> 
                </description>
                <shortDescription>
                    <![CDATA[ Test4

                    ]]> 
                </shortDescription>
                <posterImage>
                    <![CDATA[ http://a.com.com/media/motion/2012/0718/los_120718_los_bucher_on_howard.jpg

                    ]]> 
                </posterImage>
                <videoURL>
                    <![CDATA[ http://com/removed/2012/0718/los_120718_los_bucher_on_howard.mp4

                    ]]> 
                </videoURL>
            </video>
        </videos>
    </videoCollection>
</response>

你能提供一个XML的样本吗?或部分内容呢? - Sujay
已添加XML。我正试图获取“videoURL”标签中的HTTP URL。 - Matt
你确定你只有一个子节点 'Node child = e.getFirstChild();' 吗?获取所有子节点并在调试器中检查它们。 - user784540
你有检查过你发布的XML吗?你漏掉了结束标签。我同意@RafaelOsipov的观点-我认为每个节点只有一个子节点。 - Sujay
你尝试过我提供的解决方案了吗?我希望这能解决你的问题 :) - Sujay
2个回答

19

不要仅检查第一个子节点,最好检查一下该节点是否还有其他子节点。在您的情况下(我猜如果您调试了该节点,您会知道),传递给方法getCharacterDataFromElement 的节点有多个子节点。我更新了代码,这个可能会给您指向正确方向的提示:

public static String getCharacterDataFromElement(Element e) {

    NodeList list = e.getChildNodes();
    String data;

    for(int index = 0; index < list.getLength(); index++){
        if(list.item(index) instanceof CharacterData){
            CharacterData child = (CharacterData) list.item(index);
            data = child.getData();

            if(data != null && data.trim().length() > 0)
                return child.getData();
        }
    }
    return "";
}

1
在你的DocumentBuilderFactory上调用setCoalescing(true)可以确保没有为空格创建单独的DOM节点,如https://dev59.com/tF3Ua4cB1Zd3GeqP8QDh中所述。 - Papa Smurf

2

我会考虑使用getTextContent()方法。

String string = cdataNode.getTextContent();

2
这个解决方案不需要使用任何转换或调用任何特定的方法。 - Stephan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接