2014-09-04 63 views
0

我想解析一个简单的XML文件。如果我有一个波纹管XML字符串,Java 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中的标签中提取字符串?

+0

的DocumentBuilder分贝= DocumentBuilderFactory.newInstance()newDocumentBuilder(); Document doc = db.parse(new ByteArrayInputStream(xml.getBytes())); String bodyText = doc.getElementsByTagName(“body”)。item(0).getTextContent(); – DmitryKanunnikoff 2014-09-04 17:11:32

+0

尝试使用DOM解析器。在这种情况下更容易。 – DmitryKanunnikoff 2014-09-04 17:12:37

回答

0

与@BatScream

的事情是设置一个标志,当你标记“体”的开始洞察力修改,然后在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); 
     } 
    } 
} 
+2

如果多次调用字符方法,则内容块将丢失。 – BatScream 2014-09-04 17:07:52

0

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

我所做的一件事是有一组匿名类对应于标签。在开始时,我标记了我所在的元素,以便我可以使用正确的匿名类来根据元素(如错误处理,日期格式或打印相关字符到标签)。我将这些匿名内部类存储在地图中,标签作为关键字。所以在字符中,我知道我在什么元素,如果我有适当的处理程序,我会处理它。

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

2

按照SAX,默认处理文档,

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

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

所以解析器可以调用字符的方法一次或多次的一个元素中一个特定的文字说,“不要这个周末忘了我吧!”,直到整个文本阅读。

注:

应用程序必须不尝试从数组中 指定的范围外读取。

以下代码显示了如何收集单个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); 
} 
} 

'elementContent'变量将保存元素开始和结束标记之间的全部内容。

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!