【问题标题】:Why some characters are missing when i parse a xml tag using SaxParser?当我使用 SaxParser 解析 xml 标记时,为什么缺少某些字符?
【发布时间】:2013-08-27 08:25:17
【问题描述】:

我正在使用 SaxParser 在我的 android 应用程序中解析一个包含近 90000 个字符的 xml 响应。 xml 如下所示:

 <Registration>
     <Client>   
         <Name>John</Name>
         <ID>1</ID>
         <Date>2013:08:22T03:43:44</Date>
     </Client>  
     <Client>   
         <Name>James</Name>
         <ID>2</ID>
         <Date>2013:08:23T16:28:00</Date>
     </Client>
     <Client>   
         <Name>Eric</Name>
         <ID>3</ID>
         <Date>2013:08:23T19:04:15</Date>
     </Client>

     ..... 
 </Registration>

有时解析器会遗漏日期标签中的一些字符。它没有返回 2013:08:23T19:04:15 而是返回 2013:08:23T。我尝试使用以下代码行跳过响应 xml 字符串中的所有空格:

 responseStr = responseStr.replaceAll("\\s","");

然后我得到以下异常:

 Parsing exception: org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 16: not well-formed (invalid token)

以下是我用于解析的代码:

 try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            DefaultHandler handler = new DefaultHandler() {
                public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
                    tagName = qName;
                }

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

                }

                public void characters(char ch[], int start, int length) throws SAXException {
                    if(tagName.equals("Name")){
                        obj = new RegisteredUser();
                        String str = new String(ch, start, length);
                        obj.setName(str);
                    }else if(tagName.equals("ID")){
                        String str = new String(ch, start, length);
                        obj.setId(str);
                    }else if(tagName.equals("Date")){
                        String str = new String(ch, start, length);
                        obj.setDate(str);

                        users.add(obj);
                    }
                }

                public void startDocument() throws SAXException {
                    System.out.println("document started");
                }

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

            saxParser.parse(new InputSource(new StringReader(resp)), handler);

        }catch(Exception e){
            System.out.println("Parsing exception: "+e);
            System.out.println("exception");

        }

知道为什么解析器会从标签中跳过字符,我该如何解决这个问题。提前致谢。

【问题讨论】:

  • 代码在哪里?错误在您的代码中,而不是在 SAX 解析器代码中。
  • 我也添加了代码。
  • 当响应少于 60000 个字符时,相同的代码可以正常工作。那时它从来没有出过任何问题

标签: java android xml sax saxparser


【解决方案1】:

对于任何给定的文本节点,characters 可能会被多次调用。

在这种情况下,您必须自己连接结果!

原因是当解析器的一些内部缓冲区结束而文本节点的内容仍然存在时。与其扩大缓冲区(当文本节点很大时,这可能需要大量内存),而是由客户端代码处理。

你想要这样的东西:

StringBuilder textContent = new StringBuilder();

public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
    tagName = qName;
    textContent.setLength(0);
}
public void characters(char ch[], int start, int length) throws SAXException {
    textContent.append(ch, start, length);
}
public void endElement(String uri, String localName, String qName) throws SAXException {
    String text = textContent.toString();
    // handle text here
}

当然,此代码可以改进为仅跟踪您真正关心的节点的文本内容。

【讨论】:

    【解决方案2】:

    正如其他提到的characters 方法可能被多次调用,它取决于SAX 解析器实现来返回所有contiguous character data in a single chunk, or they may split it into several chunks。 请参阅文档SAX Parser characters

    【讨论】:

      【解决方案3】:

      您错误地假设文本节点中的所有字符都将被一次读取并发送到characters() 方法。事实并非如此。可以为单个文本节点多次调用 characters() 方法。

      您应该将所有字符附加到 StringBuilder,然后仅在调用 endElement() 时转换为字符串或日期。

      【讨论】:

        猜你喜欢
        • 2011-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 2023-03-19
        • 2013-03-01
        • 1970-01-01
        • 2019-11-01
        相关资源
        最近更新 更多