@Override public void onNothingSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent details = new Intent(PlaceActivity.this, Details.class);
details.putExtra("name", myArrayList.get(arg2).getName());
details.putExtra("rating", myArrayList.get(arg2).getRating());
details.putExtra("vicinity", myArrayList.get(arg2).getVicinity());
details.putExtra("lat", myArrayList.get(arg2).getLat());
details.putExtra("lon", myArrayList.get(arg2).getLon());
startActivity(details);
}
第一个XPath选择两个表,而第二个表只获取目标(第二个)表。为什么呢?
答案 0 :(得分:4)
接受的答案纠正了错误,但并没有真正解释为什么原始路径表达式出错了。
您的第一个表达式如下:
//table[//b[contains(@class, "2")]]
它有两个谓词,一个嵌套在另一个中:
//table[//b[contains(@class, "2")]]
^---------------------^ inner predicate
^--------------------------^ outer predicate
将谓词视为应用于谓词左侧上下文的过滤器。在极端情况下,这样的谓词都不会丢弃所有中间结果节点。
每个中间结果节点仅在其右侧的谓词评估为true
时保留。在内部谓词的情况下:
//b[contains(@class, "2")]
//b
生成一组中间b
元素节点(整个文档中的所有b
个元素节点),然后由谓词[contains(@class, "2")]
过滤。给定输入XML文档,谓词中的表达式仅返回true
b
元素的
但//b[contains(@class, "2")]
反过来又作为外部谓词的内容:
//table[outer predicate]
现在//table
选择整个文档中所有table
个元素节点作为中间结果,并且对于每个节点,都会检查谓词中的表达式。
重要的是,外部谓词//b[contains(@class, "2")]
将为两个 true
元素返回table
。这是因为对于它们两者而言,确实在整个文档中的某个位置存在b
元素,其class
属性包含2
。
您实际想要做的是:从每个table
元素的角度评估外部谓词表达式 - 接受的答案显示了如何执行此操作。即,在谓词中使用.//
而不是//
。
答案 1 :(得分:2)
XPath谓词[//b...]
中存在错误。它应该是[.//b...]
。
说明:
[...]
是谓词,它们仅充当过滤器。当您说a[b]
时,您选择满足谓词a
的所有[b]
个节点。如果a
和b
是元素,它将从当前上下文节点中选择包含a
元素作为子元素的所有b
元素。
//b
是AbbreviatedAbsoluteLocationPath
,并选择整个文档中的所有b
个元素节点。这两个表都在一个符合b
元素的文档中,因此无论您在何处应用它,谓词[//b]
始终为true。.//b
是AbbreviatedRelativeLocationPath
,并选择所有b
元素节点作为后代(子节点及其子节点,递归地)。谓词[.//b]
仅适用于具有后代元素table
的{{1}}元素。 b
或//b
等步骤路径表达式,当用作.//b
或[//b]
等谓词时,如果选择的节点集为 true 步路径表达式不为空。
由于[.//b]
而不是//b
,所应用的谓词不会改变任何内容。
.//b
选择整个文档中//b[contains(@class, "2")]
属性中包含“2”的所有元素。您基本上是对文档执行检查,而不是对所需class
元素下面的树执行检查,并且table
元素的文档检查都已满足,因为两者都在包含{{1}的文档中在其table
属性中包含“2”的元素。