Why did my XPath,
//android.view.ViewGroup[*/android.widget.TextView[@androidXtext='Microwaves']]
select this node,
<android.view.ViewGroup androidXclickable="true" androidXcontentDescription="ucl.flex-row" androidXenabled="true" androidXfocusable="true" androidXid="@ucl.flex-row" androidXlayout_height="147px" androidXlayout_width="1059px" androidXlayout_x="11px" androidXlayout_y="913px">`
and not any other above or below?
Full fragment:
<android.view.ViewGroup androidXenabled="true" androidXlayout_height="147px" androidXlayout_width="1059px" androidXlayout_x="11px" androidXlayout_y="913px">
<android.view.ViewGroup androidXclickable="true" androidXcontentDescription="ucl.flex-row" androidXenabled="true" androidXfocusable="true" androidXid="@ucl.flex-row" androidXlayout_height="147px" androidXlayout_width="1059px" androidXlayout_x="11px" androidXlayout_y="913px">
<android.view.ViewGroup androidXenabled="true" androidXlayout_height="147px" androidXlayout_width="1059px" androidXlayout_x="11px" androidXlayout_y="913px">
<android.view.ViewGroup androidXcontentDescription="ucl.flex-row.left-action.svg" androidXenabled="true" androidXid="@ucl.flex-row.left-action.svg" androidXlayout_height="63px" androidXlayout_width="63px" androidXlayout_x="53px" androidXlayout_y="955px">
<android.view.ViewGroup androidXenabled="true" androidXlayout_height="63px" androidXlayout_width="63px" androidXlayout_x="53px" androidXlayout_y="955px">
<android.view.ViewGroup androidXenabled="true" androidXlayout_height="0px" androidXlayout_width="0px" androidXlayout_x="53px" androidXlayout_y="955px">
<android.view.ViewGroup androidXenabled="true" androidXlayout_height="0px" androidXlayout_width="0px" androidXlayout_x="53px" androidXlayout_y="955px"/>
</android.view.ViewGroup>
</android.view.ViewGroup>
</android.view.ViewGroup>
<android.widget.TextView androidXcontentDescription="ucl.flex-row.main.text" androidXenabled="true" androidXid="@ucl.flex-row.main.text" androidXlayout_height="53px" androidXlayout_width="891px" androidXlayout_x="137px" androidXlayout_y="960px" androidXtext="Microwaves"/>
</android.view.ViewGroup>
</android.view.ViewGroup>
</android.view.ViewGroup>
CodePudding user response:
Two concepts in play here, node tests and axes:
*
is equivalent toelement()
, selecting elements without regard to name.The default axis is
child::
, so your predicate effectively starts withchild::element()
.
Therefore,
//android.view.ViewGroup[*/android.widget.TextView[@androidXtext='Microwaves']]
means to select all android.view.ViewGroup
elements with a grandchild android.widget.TextView
element that has a androidXtext
attribute value equal to 'Microwaves'
.
When you ask specifically,
and not any other above or below
aside from your sample XML having no other elements that meet the above criteria, note that if you were interpreting */
to be a wildcard that selected to all descendents, it does not. As explained above, it only skips past children elements. To select and test all descendent android.widget.TextView
elements in the predicate, instead of */android.widget.TextView
use descendent::android.widget.TextView
or descendent-or-self::android.widget.TextView
(abbreviated form: .//android.widget.TextView
).
See also
- What is the difference between .// and //* in XPath?
- What is meaning of .// in XPath?
- Difference between "//" and "/" in XPath?
CodePudding user response:
The XPath default axis is child
, so your predicate
[*/android.widget.TextView[@androidXtext='Microwaves']]
is equivalent to
[child::*/child::android.widget.TextView[@androidXtext='Microwaves']]
This predicate will select nodes with a android.widget.TextView
grandchild and the specified attribute.