Android XmlPullParser空白破解.我该如何做得更优雅



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

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

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

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

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。

所以问题是:我没有正确理解什么?我该如何在不使用丑陋的破解的情况下接受这个序列,这更符合XmlPullParser的推荐使用。

我有一种预感,这是一个有问题的XML,但它代表了我将要看到的内容,即我无法控制输入流中的元素间空白。

fwiw,XML的简单框架处理这个输入流时不会出现问题,这是我的首选方法,但由于与底层stax和epp库的依赖冲突,该包在Gradle和Android Studio中使用起来非常非常混乱,但这完全是另一个问题。

为了回答我自己的问题,我为那些在某个时候发现自己处于我的处境的开发人员提供了以下内容。但我非常期待很快得到更好的答案。

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

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

这让我相信JAXB和Simple正在验证解析器,可以轻松处理这种元素间空白,而我现在必须显式处理它,这让我非常懊恼。

缺乏理解的第二点是,Android的XmlPullParser只能通过提供一个"模式"来支持验证来创建验证解析器,这在这个例子中几乎超出了我的控制范围。

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

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

最新更新