在 JAVA 中使用 SAX 解析器从 XML 文件中提取文本节点

Posted

技术标签:

【中文标题】在 JAVA 中使用 SAX 解析器从 XML 文件中提取文本节点【英文标题】:Extracting Text Nodes From XML File Using SAX Parser in JAVA 【发布时间】:2011-09-25 12:44:48 【问题描述】:

所以我目前正在使用 SAX 尝试从我正在处理的许多 xml 文档中提取一些信息。到目前为止,提取属性值真的很容易。但是,我不知道如何从文本节点中提取实际值。

例如,在给定的 XML 文档中:

<w:rStyle w:val="Highlight" /> 
  </w:rPr>
  </w:pPr>
- <w:r>
  <w:t>Text to Extract</w:t> 
  </w:r>
  </w:p>
- <w:p w:rsidR="00B41602" w:rsidRDefault="00B41602" w:rsidP="007C3A42">
- <w:pPr>
  <w:pStyle w:val="Copy" /> 

通过从 val 获取值,我可以毫无问题地提取“突出显示”。但我不知道如何进入该文本节点并退出“要提取的文本”。

这是我迄今为止提取属性值的 Java 代码...

private static final class SaxHandler extends DefaultHandler 
    
        // invoked when document-parsing is started:
        public void startDocument() throws SAXException 
        
            System.out.println("Document processing starting:");
        

        // notifies about finish of parsing:
        public void endDocument() throws SAXException 
        
            System.out.println("Document processing finished. \n");
        

        // we enter to element 'qName':
        public void startElement(String uri, String localName, 
                String qName, Attributes attrs) throws SAXException 
        
            if(qName.equalsIgnoreCase("Relationships"))
            
                // do nothing
            
            else if(qName.equalsIgnoreCase("Relationship"))
            
                // goes into the element and if the attribute is equal to "Target"...
                String val = attrs.getValue("Target");
                // ...and the value is not null
                if(val != null)
                
                    // ...and if the value contains "image" in it...
                    if (val.contains("image"))
                    
                        // ...then get the id value
                        String id = attrs.getValue("Id");
                        // ...and use the substring method to isolate and print out only the image & number
                        int begIndex = val.lastIndexOf("/");
                        int endIndex = val.lastIndexOf(".");
                        System.out.println("Id: " + id + " & Target: " + val.substring(begIndex+1, endIndex));
                    
                
            
            else 
            
                throw new IllegalArgumentException("Element '" + 
                        qName + "' is not allowed here");
            
        

        // we leave element 'qName' without any actions:
        public void endElement(String uri, String localName, String qName) throws SAXException 
        
            // do nothing;
        
     

但我不知道从哪里开始进入该文本节点并提取其中的值。有人有什么想法吗?

【问题讨论】:

您是否考虑过使用 XPath 会容易得多... 【参考方案1】:

这是一些伪代码:

private boolean insideElementContainingTextNode;
private StringBuilder textBuilder;

public void startElement(String uri, String localName, String qName, Attributes attrs) 
    if ("w:t".equals(qName))  // or is it localName?
        insideElementContainingTextNode = true;
        textBuilder = new StringBuilder();
    


public void characters(char[] ch, int start, int length) 
    if (insideElementContainingTextNode) 
        textBuilder.append(ch, start, length);
    


public void endElement(String uri, String localName, String qName) 
    if ("w:t".equals(qName))  // or is it localName?
        insideElementContainingTextNode = false;
        String theCompleteText = this.textBuilder.toString();
        this.textBuilder = null;
    

【讨论】:

嗯,我试过了,但它没有提取任何文本。你能解释一下这段代码应该做什么吗? 在 startElement 中,检查解析器是否开始读取包含要提取的文本节点的元素。如果是,则将布尔变量设置为 true。这样,characters 方法知道它在适当的元素中,并将读取的文本存储在 StringBuilder 中。当到达元素的末尾时调用方法 endElement。因此,您可以获取 StringBuilder 的内容并将其存储在您想要的任何位置。我只将它存储在局部变量(theCompleteText)中,但如果需要,您可以将其存储在实例变量中。 你可以去掉那个布尔值并在字符方法中测试if (textBuilder != null)

以上是关于在 JAVA 中使用 SAX 解析器从 XML 文件中提取文本节点的主要内容,如果未能解决你的问题,请参考以下文章

如何让 SAX 解析器从 xml 声明中确定编码?

SAX 解析器从 endelement 获取属性

如何在 XML 中嵌入二进制数据?

在 Java 中使用 SAX 解析大型 XML

XML 解析---dom解析和sax解析

使用 SAX 在 Java 中解析 XML:价值减半