Android XmlPullParser空白黑客攻击。我怎样才能更优雅地做到这一点?

时间:2014-03-01 08:08:57

标签: android xmlpullparser android-xmlpullparser

我在Android应用程序中有一些XML,其中XmlPullParser是将XML绑定到数据模型类的推荐解决方案。 XmlPullParser的Android文档相当不错,除了如何处理元素间空格。建议的方法是检测低级别的IGNORABLE_WHITESPACE解析事件并跳过这些事件。但是对于我想接受的XML,这种方法对我不起作用。我从未看到发生过低级别的IGNORABLE_WHITESPACE事件。这使我相信我没有正确理解我的特定用例的某些方面,XmlPullParser行为,可接受的XML或可能的配置问题。

我想要接受的XML片段的简化测试用例是:

<a>  <b></b>  </a>

我使用推荐的getNextToken()方法接受这个元素的代码hack是:

            boolean hasEvent = false;
            String desc = null;
            while (!hasEvent) {
                result = xpp.nextToken();
                desc = xpp.getPositionDescription();
                Log.i(TAG, String.format("Processing: %s", desc));
                switch (result) {
                case START_TAG:
                case END_TAG:
                case END_DOCUMENT:
                    hasEvent = true;
                    break;

                case TEXT:
                    // Use a real hack to detect whitespace.
                    if (desc.contains("TEXT (whitespace)@")) {
                        hasEvent = false;
                    } else {
                        hasEvent = true;
                    }
                    break;

                default:
                    break;
                }
            }

,我看到的结果基本上是:获得START_TAG(a),得到TEXT(空白),得到START_TAG(b),得到END_TAG(b),得到TEXT(空白),得到END_TAG(a)。< / p>

所以问题是:我不正确理解的是什么?如果不诉诸丑陋的黑客,我将如何接受这个序列,更多的是与推荐使用XmlPullParser保持一致。

我有一种预感,这是一个值得怀疑的XML,但它代表了我将要呈现的内容,即我无法控制输入流中的元素间空格。

fwiw,XML的简单框架处理这个输入流没有打嗝,是我的首选方法,但由于与底层stax和epp库的依赖冲突,使用Gradle和Android Studio非常非常混乱,但这完全是另一个问题。

1 个答案:

答案 0 :(得分:0)

为了回答我自己的问题,我为那些在某些时候发现自己处境的开发者提供了以下内容。但我很快就会期待更好的答案。

至于缺乏理解,第一点是现在我明白我使用的是非验证解析器。这个声明是在Android XmlPullParser源代码/ Javadoc for isWhitespace()中做出的:

  

请注意:非验证解析器无法区分空白和可忽略的空格,除了根元素外的空格。可忽略的空格被报告为单独的事件,仅通过nextToken公开。

这让我相信JAXB和Simple正在验证解析器并且可以大步处理这个元素间空白,而我现在必须明确处理它,这让我很懊恼。

缺乏理解伞的另一个问题是,Android的XmlPullParser只能通过提供一个“模式”来支持验证来创建验证解析器,这对于这个实例来说几乎是我无法控制的。

至于处理元素间空格的更优雅的方法,我的答案是有两个方法:getNextElement(),它将返回下一个START_TAG或END_TAG事件,但丢弃文本为空格的所有TEXT事件,其他任何东西都被视为解析错误;另一个方法是getNextText(),它将从TEXT或CDSECT解析事件中返回文本,并将任何其他事件报告为错误。

正如我所说,我期待更好的答案。