Чтение вложенных тегов с парсером 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 читается только "‹" как содержимое тега

пожалуйста, помогите, мне нужно, чтобы все данные были прочитаны


person Anirban Dutta    schedule 20.12.2010    source источник
comment
Пожалуйста, опубликуйте пример ожидаемого результата. Поскольку ваш образец не содержит текстовых данных, а только вложенные теги с атрибутами, я думаю, вы, вероятно, ожидаете чего-то, что никогда не произойдет, но вам нужен некоторый контекст, чтобы быть уверенным.   -  person Don Roby    schedule 20.12.2010


Ответы (2)


Теги в вашем 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()
person Vijay Mathew    schedule 20.12.2010

Я подозреваю, что это то, что происходит не так:

new String(ch,start,length);

Здесь вы передаете char[] конструктору String, но конструктор должен принимать byte[]. В итоге вы получите искаженную строку.

Вместо этого я предлагаю вам сделать поле str StringBuilder, а не String, а затем использовать это:

builder.append(ch,start,length);

Затем вам нужно очищать StringBuilder каждый раз, когда вызывается startElement().

person skaffman    schedule 20.12.2010