【问题标题】:How can I extract all PCDATA (text) from an XML file in Java?如何从 Java 中的 XML 文件中提取所有 PCDATA(文本)?
【发布时间】:2011-05-13 09:26:22
【问题描述】:

我有一堆 XML 文件以及 DTD,每个文件都有一个 <TEXT> 部分。 TEXT 元素的 DTD 如下所示:

<!ELEMENT TEXT - - (AGENCY* | ACTION* | SUMMARY* | DATE* | FOOTNAME* | FURTHER* | SIGNER* | SIGNJOB* | FRFILING* | BILLING* | FOOTNOTE* | FOOTCITE* | TABLE* | ADDRESS* | IMPORT* | #PCDATA)+ >

这是一个示例 XML 文件的样子:

<ROOT>
  ...
  <TEXT>
  Some text that I want to extract
  <SUMMARY> Some more text </SUMMARY>
  <AGENCY> 
     An agency
     <SIGNER> Bob Smith </SIGNER>
  </AGENCY>
  </TEXT>
  ...
</ROOT>

最后,我要提取

我想提取的一些文本 还有一些文字 一个机构 鲍勃·史密斯

但是,每个&lt;TEXT&gt; 块显然在元素/排序方面或您走多远方面都不相同。在 Java 中有没有使用 DOM 的方法可以做到这一点?我更喜欢使用 DOM 而不是 SAX,但如果使用 SAX 更容易,那就这样吧。

提前致谢

【问题讨论】:

    标签: java xml xml-parsing


    【解决方案1】:

    XSLT 样式表可以工作:

    更新 #2:我怀疑这对你有用,因为你实际上使用的是 SGML 而不是 XML。赠品是您在问题中的元素声明具有 XML 中不允许的标签最小化。

    更新:修改 XML 输入和 XSLT 以仅显示 &lt;TEXT&gt; 结构中的文本。

    XML 输入

    <ROOT>
      <IGNORE>ignore this data</IGNORE>
      <TEXT>
        Some text that I want to extract
        <SUMMARY> Some more text </SUMMARY>
        <AGENCY> 
          An agency
          <SIGNER> Bob Smith </SIGNER>
        </AGENCY>
      </TEXT>
      <IGNORE>ignore this data</IGNORE>
    </ROOT>
    

    XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="text"/>
    
      <xsl:template match="/">
        <xsl:value-of select="normalize-space(/ROOT/TEXT)"/>
      </xsl:template>
    
    </xsl:stylesheet>
    

    输出

    我想提取的一些文本 Some 更多文字 代理机构 Bob Smith

    注意:此 XSLT 仅在 TEXT 是 ROOT 的子项时才有效。如果 TEXT 可能嵌套更深,您可以将“选择”更改为 select="normalize-space(//TEXT)"

    【讨论】:

    • 你是对的,它是 SGML,但到目前为止它是 XML 兼容的
    【解决方案2】:

    我不是 SAX 的忠实粉丝,但我认为它会很好地工作。

    只定义一个 sax 处理程序,但只使用 characters 方法。然后只需将接收到的字符放入StringBuilder 即可完成。

    public class textExtractor extends DefaultHandler {
    
      private StringBuilder sb = new StringBuilder();
    
      public void characters(char[] ch, int start, int length){
        for (int i=0; i<length; i++){
          sb.append(ch[i]);
        }
      }
    
      public String getText(){
        return sb.toString();
      }
    
    }
    

    【讨论】:

    • 我想我会采用这种方法。萨克斯处理程序必须是它自己的类吗?或者我可以简单地扩展我的主要方法的父类吗?
    • 您可以扩展父类,但我不认为这是一种新方法。如果你不想为此创建一个特定的类,你可以使用匿名类。
    猜你喜欢
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多