如何从JDOM获取节点内容

时间:2011-10-27 00:23:47

标签: java xml xml-parsing jdom

我正在使用import org.jdom在java中编写应用程序。*;

我的XML有效,但有时它包含HTML标记。例如,像这样:

  <program-title>Anatomy &amp; Physiology</program-title>
  <overview>
       <content>
              For more info click <a href="page.html">here</a>
              <p>Learn more about the human body.  Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p>
       </content>
  </overview>
  <key-information>
     <category>Health &amp; Human Services</category>

所以我的问题是&lt; p> overview.content节点内的标签。

我希望这段代码可行:

        Element overview = sds.getChild("overview");
        Element content = overview.getChild("content");

        System.out.println(content.getText());

但它返回空白。

如何从overview.content节点返回所有文本(嵌套标签和全部)?

由于

7 个答案:

答案 0 :(得分:16)

content.getText()提供即时文本,该文本仅对包含文本内容的叶元素有用。

欺骗是使用org.jdom.output.XMLOutputter(使用文字模式CompactFormat

public static void main(String[] args) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    String xmlFileName = "a.xml";
    Document doc = builder.build(xmlFileName);

    Element root = doc.getRootElement();
    Element overview = root.getChild("overview");
    Element content = overview.getChild("content");

    XMLOutputter outp = new XMLOutputter();

    outp.setFormat(Format.getCompactFormat());
    //outp.setFormat(Format.getRawFormat());
    //outp.setFormat(Format.getPrettyFormat());
    //outp.getFormat().setTextMode(Format.TextMode.PRESERVE);

    StringWriter sw = new StringWriter();
    outp.output(content.getContent(), sw);
    StringBuffer sb = sw.getBuffer();
    System.out.println(sb.toString());
}

<强>输出

For more info click<a href="page.html">here</a><p>Learn more about the human body. Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p>

请浏览其他formatting选项,并根据需要修改上述代码。

  

“用于封装XMLOutputter格式选项的类。典型用户可以使用getRawFormat()获取的标准格式配置(无空白更改),getPrettyFormat()(空白美化)和getCompactFormat()(空格规范化)。” p>

答案 1 :(得分:4)

您可以尝试使用method getValue()进行最接近的近似,但这样做可以将元素中的所有文本和后代连接在一起。这不会以任何形式提供<p>标记。如果该标记在您所显示的XML中,则它已成为XML标记的一部分。它需要包含在&lt;p&gt;中或嵌入CDATA部分,以便视为文本。

或者,如果您知道XML中可能出现或未出现的所有元素,则可以应用XSLT转换,将不作为标记的内容转换为纯文本。

答案 2 :(得分:3)

好吧,也许这就是你所需要的:

import java.io.StringReader;

import org.custommonkey.xmlunit.XMLTestCase;
import org.custommonkey.xmlunit.XMLUnit;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.testng.annotations.Test;
import org.xml.sax.InputSource;

public class HowToGetNodeContentsJDOM extends XMLTestCase
{
    private static final String XML = "<root>\n" + 
            "  <program-title>Anatomy &amp; Physiology</program-title>\n" + 
            "  <overview>\n" + 
            "       <content>\n" + 
            "              For more info click <a href=\"page.html\">here</a>\n" + 
            "              <p>Learn more about the human body.  Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p>\n" + 
            "       </content>\n" + 
            "  </overview>\n" + 
            "  <key-information>\n" + 
            "     <category>Health &amp; Human Services</category>\n" + 
            "  </key-information>\n" + 
            "</root>";
    private static final String EXPECTED = "For more info click <a href=\"page.html\">here</a>\n" + 
            "<p>Learn more about the human body.  Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p>";

    @Test
    public void test() throws Exception
    {
        XMLUnit.setIgnoreWhitespace(true);
        Document document = new SAXBuilder().build(new InputSource(new StringReader(XML)));
        List<Content> content = document.getRootElement().getChild("overview").getChild("content").getContent();
        String out = new XMLOutputter().outputString(content);
        assertXMLEqual("<root>" + EXPECTED + "</root>", "<root>" + out + "</root>");
    }
}

输出:

PASSED: test on instance null(HowToGetNodeContentsJDOM)

===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================

我正在使用带有泛型的JDom:http://www.junlu.com/list/25/883674.html

编辑:实际上与Prashant Bhate的回答并没有那么大的不同。也许你需要告诉我们你错过了什么......

答案 3 :(得分:1)

如果您还要生成XML文件,您应该能够将您的html数据封装在<![CDATA[]]>中,以便XML解析器不会对其进行解析。

答案 4 :(得分:0)

问题是<content>节点没有文本子节点;它有一个恰好包含文字的<p>孩子。

试试这个:

Element overview = sds.getChild("overview");
Element content = overview.getChild("content");
Element p = content.getChild("p");
System.out.println(p.getText());

如果您想要所有直接子节点,请致电p.getChildren()。如果要获取所有子节点,则必须递归调用它。

答案 5 :(得分:0)

不是特别漂亮,但工作正常(使用JDOM API):

public static String getRawText(Element element) {
    if (element.getContent().size() == 0) {
        return "";
    }

    StringBuffer text = new StringBuffer();
    for (int i = 0; i < element.getContent().size(); i++) {
        final Object obj = element.getContent().get(i);
        if (obj instanceof Text) {
            text.append( ((Text) obj).getText() );
        } else if (obj instanceof Element) {
            Element e = (Element) obj;
            text.append( "<" ).append( e.getName() );
            // dump all attributes
            for (Attribute attribute : (List<Attribute>)e.getAttributes()) {
                text.append(" ").append(attribute.getName()).append("=\"").append(attribute.getValue()).append("\"");
            }
            text.append(">");
            text.append( getRawText( e )).append("</").append(e.getName()).append(">");
        }
    }
    return text.toString();
}

Prashant Bhate的解决方案虽然更好!

答案 6 :(得分:0)

如果要输出某些JSOM节点的内容,只需使用

System.out.println(new XMLOutputter().outputString(node))