Java XML Parser - 如何收集或计算某个标记

时间:2014-09-04 16:37:14

标签: java xml parsing sax

我正在尝试解析一个简单的XML文件。如果我有一个波纹管XML字符串,

<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

我只想从<body> ... </body>中提取字符串。我正在使用SAXParser和默认处理程序。我通过在DefaultHandler中的“characters”方法中显式添加print语句,成功打印出所有字符串标签。但我不确定这个角色方法的位置和方法,以及如何控制它。

我知道如何在startElement中发现某个标记,但是如何从startElement中的标记中提取字符串?

4 个答案:

答案 0 :(得分:2)

根据SAX,Default Handler文档,

public void characters(char[] ch,
                       int start,
                       int length)
                throws SAXException
  

Parser将调用此方法来报告每个字符块   数据。 SAX解析器可以在单个中返回所有连续的字符数据   大块,或者他们可能将它分成几个块;但是,所有的   任何单个事件中的字符必须来自同一个外部实体   以便定位器提供有用的信息。

因此,解析器可以为一个元素中的特定文本调用一次或多次字符方法,然后说,&#34;本周末不要忘记我!&#34;,直到读完整个文本。

注意:

  

应用程序不得尝试从数组外部读取数据   指定范围。

以下代码显示了如何在单个XML元素中收集文本。

boolean isTagInScope = false;
StringBuilder elementContent = new StringBuilder();
public void startElement(String namespaceURI, String lName, String qName,
Attributes attributes) throws SAXException 
{
 isTagInScope = true;
}

public void endElement(String namespaceURI, String sName, String qName)
throws SAXException  throws SAXException {
 isTagInScope = false;
}

public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
if(isTagInScope)
{
 String content = new String(arg0, arg1, arg2);
 elementContent.append(content);
}
}

&#39; elementContent&#39;变量将保存元素的开始和结束标记之间的整个内容。

答案 1 :(得分:1)

您可以使用Java SE中的javax.xml.xpath API来提取元素的文本。

演示代码

import javax.xml.xpath.*;
import org.xml.sax.InputSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        InputSource inputSource = new InputSource("input.xml");
        XPath xPath = XPathFactory.newInstance().newXPath();
        String text = xPath.evaluate("/note/body", inputSource);
        System.out.println(text);
    }

}

<强>输出

Don't forget me this weekend!

答案 2 :(得分:0)

  

通过@BatScream的洞察力进行修改

当你得到标签'body'的开头时,设置一个标志,然后在characters方法中,如果标志为true,你就拥有它。

public class NoteHandler extends DefaultHandler {
    private static final STRING TAG_BODY = "body";
    private boolean bodyFlag = false;
    private StringBuilder body = new StringBuilder();

    public void startDocument() throws SAXException {}

    public void endDocument() throws SAXException {}

    public void startElement(String uri, String localName, tring qName, Attributes attributes) throws SAXException {
        bodyFlag = TAG_BODY.equals(qName); // true when body tag
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(bodyFlag) {
            bodyFlag = false;
            System.out.println(body.toString());
        }
    }

    public void characters(char ch[], int start, int length) throws SAXException {
        if(bodyFlag) {
            body.append(new String(ch, start, length);
        }
    }
}

答案 3 :(得分:0)

您可以设置一个标志,或使用枚举来指示您在开始时使用的元素,并在字符方法中对其进行相应的解释。

我做的一件事是拥有一组与标签相对应的匿名类。在开始时,我标记我所在的元素,以便我可以使用正确的匿名类来执行我想要的基于元素的字符(例如错误处理,日期格式化,或者在打印相关字符的情况下)到标签)。我将那些匿名内部类存储在一个以标记为关键字的地图中。所以在角色中,我知道我在哪个元素,如果我有一个合适的处理程序,我会处理它。

将xml输入转换为类时,此方法非常有用。