使用sax解析器读取嵌套标记

时间:2010-12-20 11:33:24

标签: java xml sax

我正在尝试使用以下标记读取xml文件,但是sax解析器无法读取嵌套标记,如

<active-prod-ownership>
  <ActiveProdOwnership>
    <Product code="3N3" component="TRI_SCORE" orderNumber="1-77305469" />
  </ActiveProdOwnership>
</active-prod-ownership> 

这是我正在使用的代码

public class LoginConsumerResponseParser extends DefaultHandler {
 // ===========================================================
 // Fields
 // ===========================================================
 static String str="default";
 private boolean in_errorCode=false;
 private boolean in_Ack=false;
 private boolean in_activeProdOwnership= false;
 private boolean in_consumerId= false;
 private boolean in_consumerAccToken=false;


  public void startDocument() throws SAXException {
  Log.e("i am ","in start document");
 }


 public void endDocument() throws SAXException {
  // Nothing to do
  Log.e("doc read", " ends here");
 }

 /** Gets be called on opening tags like: 
  * <tag> 
  * Can provide attribute(s), when xml was like:
  * <tag attribute="attributeValue">*/

 public void startElement(String namespaceURI, String localName,
   String qName, Attributes atts) throws SAXException {
  if(localName.equals("ack")){
   in_Ack=true;
  }
  if(localName.equals("error-code")){
   in_errorCode=true;
  }
  if(localName.equals("active-prod-ownership")){
   Log.e("in", "active product ownership");
   in_activeProdOwnership=true;
  }
  if(localName.equals("consumer-id")){
   in_consumerId= true;
  }
  if(localName.equals("consumer-access-token"))
  {
   in_consumerAccToken= true;
  }
 }

 /** Gets be called on closing tags like: 
  * </tag> */

 public void endElement(String namespaceURI, String localName, String qName)
 throws SAXException {
  if(localName.equals("ack")){
   in_Ack=false;
  }
  if(localName.equals("error-code")){
   in_errorCode=false;
  }
  if(localName.equals("active-prod-ownership")){
   in_activeProdOwnership=false;
  }
  if(localName.equals("consumer-id")){
   in_consumerId= false;
  }
  if(localName.equals("consumer-access-token"))
  {
   in_consumerAccToken= false;
  }
 }

 /** Gets be called on the following structure: 
  * <tag>characters</tag> */

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

  if(in_Ack){
  str= new String(ch,start,length);
  }
  if(str.equalsIgnoreCase("success")){
  if(in_consumerId){

  }
  if(in_consumerAccToken){

  }
  if(in_activeProdOwnership){
   str= new String(ch,start,length);
   Log.e("active prod",str);
  }
  }
 }
}

但在到达标签in_activeProdOwnersip时只读“&lt;”作为标签的内容

请帮助我需要阅读整个数据

2 个答案:

答案 0 :(得分:3)

XML文件和解析器中的标记不匹配。我认为你是混合标签与属性名称。以下是正确解析您的示例XML的代码:

public class LoginConsumerResponseParser extends DefaultHandler {
    public void startDocument() throws SAXException {
        System.out.println("startDocument()");
    }

    public void endDocument() throws SAXException {
        System.out.println("endDocument()");
    }

    public void startElement(String namespaceURI, String localName,
                             String qName, Attributes attrs) 
        throws SAXException {

        if (qName.equals("ActiveProdOwnership")) {
            inActiveProdOwnership = true;
        } else if (qName.equals("Product")) {
            if (!inActiveProdOwnership) {
                throw new SAXException("Product tag not expected here.");
            }
            int length = attrs.getLength();
            for (int i=0; i<length; i++) {
                String name = attrs.getQName(i);
                System.out.print(name + ": ");
                String value = attrs.getValue(i);
                System.out.println(value);            
            }
        }            
    }

    public void endElement(String namespaceURI, String localName, String qName)
        throws SAXException {

        if (localName.equals("ActiveProdOwnership"))
            inActiveProdOwnership = false;
    }

    public void characters(char ch[], int start, int length) {
    }

    public static void main(String args[]) throws Exception {
        String xmlFile = args[0];
        File file = new File(xmlFile);
        if (file.exists()) {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            DefaultHandler handler = new Test();
            parser.parse(xmlFile, handler);
        }
        else {
            System.out.println("File not found!");
        }
    }

    private boolean inActiveProdOwnership = false;
}

示例运行将产生以下输出:

startDocument()
code: 3N3
component: TRI_SCORE
orderNumber: 1-77305469
endDocument()

答案 1 :(得分:0)

我怀疑这是出了什么问题:

new String(ch,start,length);

在这里,您将char[]传递给String构造函数,但构造函数应该使用byte[]。最终结果是你得到一个受损的字符串。

我建议您将str字段设为StringBuilder,而不是String,然后使用此字段:

builder.append(ch,start,length);

然后,您需要在每次调用StringBuilder时清除startElement()