I'm using Eclipse to run an XSL 2.0 (XPATH 2.0), and I have the following source:
<testTop>
<Level1 id="abc" Text="from 1-2"/>
<Level1 id="pqr" Text="from 3-44" />
<Level1 id="xyz" Text="from 49-101" />
</testTop>
When I test the following expression in Eclipse, //*[matches(#Text, '\d+-\d+')] I get the right nodes, but not the Text attributes themselves
Level1 ID=abc
Level1 ID=pqr
Level1 ID=xyz
... whereas //#Text gives me the Text attributes. Can anyone help me to understand why?? I'd like to get the Text attribute values and parse them using string functions. THE END RESULT SHOULD LOOK LIKE THIS:
<output originalText="from 1-2" value1="1" value2="2" />
Shouldn't I be getting all the attributes that are part of each node that matched?
Your XPath is selecting the elements that have the attributes you want. If you want to select the #Text that match your pattern, you need to adjust your XPath to select the attributes rather than the element.
You could use this XPath:
//*[matches(#Text, '\d+-\d+')]/#Text
or this XPath:
//*/#Text[matches(., '\d+-\d+')]
Related
I want to write a common XPath for the result displayed for my searched text 'Automation Server'
The same text is displayed for td HTML tags as well as for div html tags as shown below, and I wrote XPath as below based on my understanding by going through different article
displayed_text = //td[contains(text(),'Automation Server') or div[contains(text(),' Automation Server ')]
<td role="cell" mat-cell="" class="mat-cell cdk-cell cdk-column-siteName mat-column-siteName ng-star-inserted">Automation Server</td>
<div class="change-list-value ng-star-inserted"> Automation Server </div>
The operator you are looking for in XPath is |. It is a union operator and will return both sets of elements.
The XPath you are looking for is
//td[contains(text(),'Automation Server')] | //div[contains(text(),'Automation Server')]
This XPath,
//*[self::td or self::div][text()[normalize-space()='Automation Server']]
will select all td or div elements with an immediate text node whose normalize string value equals 'Automation Server'.
Cautions regarding other answers here
| is not logical-OR or "OR-like".
It is a union operator over node sets (XPath 1.0) or sequences (XPath 2.0+), not boolean values.
See: Logical OR in XPath? Why isn't | working?
contains(text(), "string") only tests the first text node child.
See: Why is contains(text(), "string" ) not working in XPath?
A few alternatives to JeffC answer, using common properties for both:
1. use the * as a wildcard for any element:
//*[contains(#class,'ng-star-inserted') and normalize-space(text())='Automation Server']
2. use in addition the local-name() function to narrow down the names of the elements:
//*[local-name()[.='td' or .='div']][contains(#class,'ng-star-inserted') and normalize-space(text())='Automation Server']
The normalize-space() function can be used to clean-up the optional white space, so a = operator can be used.
You could use the following XPath to test the local-name() of the element in a predicate and whether it's text() contains the phrase:
//*[(local-name() = "td" or local-name() = "div") and contains(text(), "Automation Server")]
I have a question about extracting a value with xpath
Some part of the xml:
<mark:info>
<mark:Information name="Adress" answer="SomeStreet"/>
<mark:Information name="PhoneNumber" answer="123456789"/>
</mark:info>
I want to receive the text "SomeStreet" with extractValue function in mysql
I was trying to create an xpath expression like
//mark:info/mark:Information[#name='Adress']
but I'm receiving the whole node. I need just the text "SomeStreet" but I'm not sure how to do it.
The xpath //mark:Information[#name="Adress"]/#answer should give SomeStreet
BTW shouldn't your xml have a xmlns specifying what is mark like :
<mark:info xmlns:mark="http://example.com"> ?
I am aware that I can directly use:
driver.FindElement(By.XPath("//ul[3]/li/ul/li[7]")).Text
to get the text .. but I am trying get the text by using Xpath and combination of different attributes like text(), contains() etc.
//ul[3]/li/ul/li//[text()='My Data']
Please suggest me different ways that I can handle this ... except the one I mentioned.
<li class="ng-binding ng-scope selectedTreeElement" ng-click="orgSelCtrl.selectUserSessionOrg(child);" ng-class="{selectedTreeElement: child.organizationId == orgSelCtrl.SelectedOrg.organizationId}" ng-repeat="child in node.childOrgs" style="background-color: transparent;"> My Data </li>
looks like you have extra "/" in your xpath and you miss dot:
//ul[3]/li/ul/li//[text()='My Data']
try this:
.//ul[3]/li/ul/li[text()='My Data']
BUT you are use xpath only for find elements, but not for reading its attributes. If you need to read attribute or text inside of it, you need to use selenium after search.
.Text of a WebElement would just return you the text of an element.
If you want to make expectations about the text, check the text() inside the XPath expression, e.g.:
//ul[3]/li/ul/li[text()='My Data']
or, using contains():
//ul[3]/li/ul/li[contains(text(), 'My Data')]
There are other functions you can make use of, see Functions - XPath.
You can also combine it with other conditions. For instance:
//ul[3]/li/ul/li[contains(#class, 'selectedTreeElement') and contains(text(), 'My Data')]
Hi how would I select all link when they have the following id.
<a id="List_ctl01_link3" class="content" href=link1.aspx">
<a id="List_ctl02_link3" class="content" href=link2.aspx">
<a id="List_ctl03_link3" class="content" href=link3.aspx">
<a id="List_ctl04_link3" class="content" href=link4.aspx">
And so on...
Please note that the last part "link3" is important, and must be included in the Xpath.
I'm using C# and Html agility pack.
Hi how would I select all link
when they have the following id
Use this XPath expression:
//a[#id[starts-with(.,'List_ctl')][substring(.,string-length()-5)='_link3']]
Note: There is no fn:ends-with() in XPath 1.0. Use last predicate instead.
Use:
//a[#id[starts-with(.,'List_ctl')
and
substring(.,string-length()-5)='_link3'
and
floor(substring-before(substring_after(.,'List_ctl'),'_'))
=
floor(substring-before(substring_after(.,'List_ctl'),'_'))
]
]
This XPath expression selects all a elements in the document whose id attribute has string value with all of the following properties:
Starts with the string 'List_ctl' .
Ends with the string '_link3' .
The substring surrounded by 'List_ctl' and '_' is a representation of an integer.
In case you use xpath 2.0 you can try match/matches functions and use regular expressions. If you are with xpath 1.0 probably you will have to write your custom attribute parser (take a look at xsl:function). AFAIR the match function is available only xpath 2.0.
Probably #id[starts-with(., 'List_ct') and ends-with(., 'link3')] is another way to do it.
While trying to parse html using Yahoo Query Language and xpath functionality provided by YQL, I ran into problems of not being able to extract “text()” or attribute values.
For e.g.
perma link
select * from html where url="http://stackoverflow.com"
and xpath='//div/h3/a'
gives a list of anchors as xml
<results>
<a class="question-hyperlink" href="/questions/661184/filling-the-text-area-with-the-text-when-a-button-is-clicked" title="In ASP.net, I need the code to fill the text area (in the form) when a button is clicked. Can you help me through by showing a simple .aspx code containing the script tag? ">Filling the text area with the text when a button is clicked</a>...
</results>
Now when I try to extract the node value using
select * from html where url="http://stackoverflow.com"
and xpath='//div/h3/a/text()'
I get results concatenated rather than a node list
e.g.
<results>Xcode: attaching to a remote process for debuggingWhy is b
…… </results>
How do I separate it into node lists and how do I select attribute values ?
A query like this
select * from html where url="http://stackoverflow.com"
and xpath='//div/h3/a[#href]'
gave me the same results for querying div/h3/a
YQL requires the xpath expression to evaluate to an itemPath rather than node text. But once you have an itemPath you can project various values from the tree
In other words an ItemPath should point to the Node in the resulting HTML rather than text content/attributes. YQL returns all matching nodes and their children when you select * from the data.
example
select * from html where url="http://stackoverflow.com" and xpath='//div/h3/a'
This returns all the a's matching the xpath. Now to project the text content you can project it out using
select content from html where url="http://stackoverflow.com" and xpath='//div/h3/a'
"content" returns the text content held within the node.
For projecting out attributes, you can specify it relative to the xpath expression. In this case, since you need the href which is relative to a.
select href from html where url="http://stackoverflow.com" and xpath='//div/h3/a'
this returns
<results>
<a href="/questions/663973/putting-a-background-pictures-with-leds"/>
<a href="/questions/663013/advantages-and-disadvantages-of-popular-high-level-languages"/>
....
</results>
If you needed both the attribute 'href' and the textContent, then you can execute the following YQL query:
select href, content from html where url="http://stackoverflow.com" and xpath='//div/h3/a'
returns:
<results> double pointer const issue issue... </results>
Hope that helps. let me know if you have more questions on YQL.