【问题标题】:Parsing only CDATA with SAXParser使用 SAXParser 仅解析 CDATA
【发布时间】:2012-07-30 14:21:04
【问题描述】:

快速提问:

如果我有这样的 XML:

<?xml version="1.0" encoding="utf-8"?>
<cop xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="cop.xsd">
    <auth>
        <uid mioattributo="20">16<![CDATA[
function matchwo(a,b) ]]></uid>
    </auth>
</cop>

所以uid 有两个孩子对吧? Node.CDATA_SECTION_NODE 之一和Node.TEXT_NODE 之一。

实现这个快速类(扩展通常的 DefaultHandler):

public class MyHandler extends DefaultHandler {
    /**
     * Logger for this class
     */
    private static final Log log = LogFactory.getLog(MyHandler.class);
    private StringBuilder sb;

    @Override
    public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    System.out.println("STARTUri: " + uri);
    System.out.println("STARTLocalName: " + localName);
    System.out.println("STARTqName: " + qName);
//  for(int i=0;i<attributes.getLength();i++) {
//      System.out.println("LocalName: "+attributes.getLocalName(i));
//      System.out.println("Type: "+attributes.getType(i));
//      System.out.println("qName: "+attributes.getQName(i));
//      System.out.println("URI: "+attributes.getURI(i));
//      System.out.println("Value: "+attributes.getValue(i));
//  }
    sb = new StringBuilder();
    //super.startElement(uri, localName, qName, attributes);
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
    sb.append(ch, start, length);
    System.out.println("TEMPORARY: " + sb.toString());
    System.out.println();
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
    System.out.println("ENDUri: " + uri);
    System.out.println("ENDLocalName: " + localName);
    System.out.println("ENDqName: " + qName);
    System.out.println("Content: " + sb.toString());
    sb.replace(0, sb.length()-1,"");
    }

}

输出的解析是这样的:

Is Validating: true
STARTUri: 
STARTLocalName: cop
STARTqName: cop
TEMPORARY: 


STARTUri: 
STARTLocalName: auth
STARTqName: auth
TEMPORARY: 


STARTUri: 
STARTLocalName: uid
STARTqName: uid
TEMPORARY: 16

TEMPORARY: 16
function matchwo(a,b) 

ENDUri: 
ENDLocalName: uid
ENDqName: uid
Content: 16
function matchwo(a,b) 
TEMPORARY:  


ENDUri: 
ENDLocalName: auth
ENDqName: auth
Content:  

TEMPORARY:  


ENDUri: 
ENDLocalName: cop
ENDqName: cop
Content:    

从输出中我们可以看到characters() 方法在节点uid 内被调用了两次,因此它可以识别两个孩子。有没有办法知道哪个是 CDATA 哪个是 TEXT?

【问题讨论】:

    标签: java xml-parsing sax


    【解决方案1】:

    您应该查看LexicalHandler,它告诉您有关 CDATA 开始/结束的信息。

    请注意,SAX 解析器可以根据需要随意调用您的 characters() 方法多次(或多次),以便您构建一个字符串(您只知道在 endElement()被调用),并且您不能依赖它来确定文档结构。

    【讨论】:

    • 嘿布莱恩。所以基本上 LexicalHandler 扩展 DefaultHandler2 扩展 DefaultHandler 所以我会同时拥有节点的内容和节点的类型,对吧?
    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 2015-02-28
    相关资源
    最近更新 更多