【问题标题】:How to get node contents from JDOM如何从 JDOM 获取节点内容
【发布时间】:2011-10-27 00:23:46
【问题描述】:

我正在使用 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>

所以我的问题在于overview.content节点内的

标签。

我希望这段代码可以工作:

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

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

但它返回空白。

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

谢谢

【问题讨论】:

  • 嗨,当文本与其他节点混合时,如何递归地展平内容节点。例如,超链接位于句子的中间。我添加了赏金以寻求帮助。
  • 需要获取内容标签内的所有HTML,包括链接和有序列表。谢谢

标签: java xml xml-parsing jdom


【解决方案1】:

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()(空白归一化)得到的标准格式配置。”

【讨论】:

    【解决方案2】:

    您可以尝试使用method getValue() 来获得最接近的近似值,但这会将元素内的所有文本和后代连接在一起。这不会以任何形式为您提供&amp;lt;p&amp;gt; 标签。如果该标记在您的 XML 中,如您所示,它已成为 XML 标记的一部分。它需要包含为 &amp;lt;p&amp;gt; 或嵌入到 CDATA 部分中才能被视为文本。

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

    【讨论】:

    • 对于那些不需要混合内容中的元素名称的人来说是完美的答案。谢谢!
    【解决方案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 的回答没有太大区别。也许您需要告诉我们您缺少什么...

    【讨论】:

      【解决方案4】:

      如果您还生成 XML 文件,您应该能够将您的 html 数据封装在 &lt;![CDATA[]]&gt; 中,这样它就不会被 XML 解析器解析。

      【讨论】:

      • 不,很遗憾我不生成 XML,我只需要使用它。
      【解决方案5】:

      问题是&lt;content&gt; 节点没有文本子节点;它有一个恰好包含文本的 &lt;p&gt; 子级。

      试试这个:

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

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

      【讨论】:

      • 然后手动将元素类型节点转换为文本表示...可能比我想象的要简单。
      【解决方案6】:

      不是特别漂亮但工作正常(使用 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 的解决方案更好!

      【讨论】:

        【解决方案7】:

        如果你想输出一些JSOM节点的内容就用

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

        【讨论】:

          猜你喜欢
          • 2012-05-08
          • 1970-01-01
          • 1970-01-01
          • 2012-05-15
          • 1970-01-01
          • 2012-10-22
          • 2020-06-22
          • 1970-01-01
          • 2020-03-10
          相关资源
          最近更新 更多