【问题标题】:Android: error in XML parsing with SAX - truncation of the text due to wrong "length" in "characters" voidAndroid:使用 SAX 解析 XML 时出错 - 由于“字符”无效中的错误“长度”而截断文本
【发布时间】:2014-02-15 13:06:48
【问题描述】:

我使用的是 SAX 解析器,有时我会遇到这个问题:在“字符”空白中,长度错误(4 个字符而不是 7 个),并且我只读取了文本的一部分。

也许有人知道为什么我有时会遇到这个问题...

非常感谢!

这是解析后的 XML 文件中我遇到问题的部分(第一个元素的解析“TagPosition”是“258”而不是“258 614”——如果完美的话,其余的都是!!):

XML

....
<LocationTag>
     <Tag>
          <TagID>#201401116505.1.1.2.1</TagID>
          <Zmin>0</Zmin>
          <TagPosition>258 614</TagPosition>
          <MotionNode>4</MotionNode>
          <TagPointRef>#201401116505.1.1.2</TagPointRef>
     </Tag>
     <Tag>
          <TagID>#201401116505.1.1.2.2</TagID>
          <Zmin>0</Zmin>
          <TagPosition>272 486</TagPosition>
          <MotionNode>1</MotionNode>
          <TagPointRef>#201401116505.1.1.2</TagPointRef>
     </Tag>
</LocationTag>
....

还有我的代码:

public class EnvironmentDataParse extends DefaultHandler{

    String TAG = "XMLHelper";

    Boolean currTag = false;
    String currTagVal = "";
    private Boolean inTag = false;

    public void get() {
        try {       
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser mSaxParser = factory.newSAXParser();
            XMLReader mXmlReader = mSaxParser.getXMLReader();
            mXmlReader.setContentHandler(this);
            mXmlReader.parse(new InputSource(getResources().openRawResource(SharedValues.EnvirFile)));  //read xml from res folder
        } catch(Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if(currTag) {
            currTagVal = currTagVal + new String(ch, start, length);
            currTag = false;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        currTag = false;     
        float[] currTagVal_float;

    if(localName.equalsIgnoreCase("Boundary"))
            boundary.setBoundary(currTagVal);

        else if(localName.equalsIgnoreCase("MotionNode")){
            if (inTag) {locTag.setMotionNode(currTagVal);}
            else{point.setMotionNode(currTagVal);}
        }

        else if(localName.equalsIgnoreCase("Point"))
            placePoint.add(point);

        else if(localName.equalsIgnoreCase("TagID"))
            locTag.setTagID(currTagVal);

        else if(localName.equalsIgnoreCase("TagPosition"))
        {               
            Log.i(TAG, "TAG: " + localName);
                Log.i(TAG, "currTagVal: " + currTagVal);
            locTag.setTagPosition(currTagVal);}

        else if(localName.equalsIgnoreCase("TagPointRef"))
            locTag.setTagPointRef(currTagVal);

        else if(localName.equalsIgnoreCase("Tag"))
            locationTag.add(locTag);
        }

    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {


        currTag = true;
        currTagVal = "";
        if(localName.equals("head"))
            boundary = new BoundaryValue();

        else if(localName.equals("Tag")){
            inTag = true;
            locTag = new TagValue();}           
    }
}

LogCat 显示了这个(“258”而不是“258 614”):

01-24 14:24:46.512: D/dalvikvm(25652): Late-enabling CheckJNI
01-24 14:24:46.527: E/jdwp(25652): Failed sending reply to debugger: Broken pipe
01-24 14:24:46.527: D/dalvikvm(25652): Debugger has detached; object registry had 1 entries
01-24 14:24:46.647: I/XMLHelper(25652): TAG: TagPosition
01-24 14:24:46.647: I/XMLHelper(25652): currTagVal: 258 
01-24 14:24:46.652: I/XMLHelper(25652): TAG: TagPosition
01-24 14:24:46.652: I/XMLHelper(25652): currTagVal: 272 486
01-24 14:24:46.657: D/dalvikvm(25652): GC_CONCURRENT freed 185K, 8% free 3347K/3604K, paused 2ms+3ms, total 21ms

【问题讨论】:

  • 'Broken Pipe' 通常意味着我只需要重新启动我的模拟器/手机。先试试。哦,还要去掉空格 str= str.replaceAll("\\s+", "");
  • 我试过了,还是同样的问题!我需要空格,因为它们是 2 个不同的值,我需要它们两个。但即使没有空格,我也得到:第一个是“258”,第二个是“272486”,所以一样......
  • 在其他一些测试之后,它只读取了这一行中的 3 个字符:如果改为在“258 614”上我放入我的文件“25 614”,解析后我得到“25 6”,如果我输入“2 614”,我会读到“2 61” - 知道为什么这个限制只有 3 个字符,然后它读得更多没有问题???

标签: android xml-parsing sax


【解决方案1】:
 @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {


        currTag = true;
        currTagVal = "";
        if(localName.equals("LocationTag"))
            boundary = new BoundaryValue();

        else if(localName.equals("Tag")){
            inTag = true;
            locTag = new TagValue();}           
    }

【讨论】:

  • 我发布的代码和文件只是整个事情的一部分,也许我剪得太多了,然后似乎不正确!但它适用于除第一个 TagPosition 的第二个值之外的所有内容......
【解决方案2】:

您的characters 方法设置为仅在第一次调用时收集。

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    if(currTag) {
        currTagVal = currTagVal + new String(ch, start, length);
        currTag = false;
    }
}

线

        currTag = false;

正在阻止 characters 方法收集所有数据。永远不能保证全部一起显示,并且此代码使以后对该方法的调用什么都不做。

实际上我怀疑你根本不需要currTag 字段,因为它仅用作此方法中的if 条件,并且在startElement 中设置为true,在endElement 中设置为false。

您可以将此方法简化为

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    currTagVal = currTagVal + new String(ch, start, length);
}

【讨论】:

  • 谢谢,这似乎是问题所在,没有这条线它可以工作!!
猜你喜欢
  • 2013-12-05
  • 1970-01-01
  • 2016-03-24
  • 2010-11-21
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多