I am trying to evaluate certain XPath expressions with libxml 2.8.0 and am getting error messages with functions. It is not clear to me whether libxml implements the whole or a subset of the XPath specification. Is there any resource clearly identifying what is implemented and how to use it?
In my specific case, one expression I am trying to evaluate is:
/TemporalInformation/RecipeInformation[fn:exists(./ActionToActionRelation[fn:contains(./#actionA,'cook') and fn:exists(./IngredientA[fn:contains(./#classes,'onion')])])]
I am using libxml through the XML::LibXML Perl module, but I have also tried my expression with the xpath1.c example tool available from xmlsoft.org, and got the same error messages:
$ ./xpath-tester data/fk.xml "/TemporalInformation/RecipeInformation[fn:exists(.> /ActionToActionRelation[fn:contains(./#actionA,'cook') and fn:exists(./IngredientA[fn:contains(./#classes,'onion')])])]" "fn=http://www.w3.org/2005/xpath-functions"
xmlXPathCompOpEval: function contains not found
XPath error : Unregistered function
xmlXPathCompOpEval: function exists not found
XPath error : Unregistered function
XPath error : Invalid expression
XPath error : Stack usage errror
Error: unable to evaluate xpath expression "/TemporalInformation/RecipeInformation[fn:exists(./ActionToActionRelation[fn:contains(./#actionA,'cook') and fn:exists(./IngredientA[fn:contains(./#classes,'onion')])])]"
Usage: ./xpath-tester <xml-file> <xpath-expr> [<known-ns-list>]
where <known-ns-list> is a list of known namespaces
in "<prefix1>=<href1> <prefix2>=href2> ..." format
I have tried with and without the fn namespace, both with xpath.c and my Perl script, and got the same result.
The libxml XPath implementation is only XPath 1.0, so 2.0-only functions such as exists aren't available. In 1.0 you only have a few core functions - there's starts-with but not ends-with, no regular expression support, no date handling, etc. and there's no strong typing and none of the higher-level constructs like if and for.
So to answer your question, yes, it does support the whole of XPath, but only XPath 1.0.
Related
I am unable to figure out why the cypress xpath is not working with the type(). I have two command functions: one that looks for the element using cy.get() and one that uses cy.xpath(). Unfortunately, this is a dynamic field so I have to use xpath.
(https://i.stack.imgur.com/wXl9q.png)
This is how I am using the above command.
(https://i.stack.imgur.com/snVn7.png)
Error:
(https://i.stack.imgur.com/08G32.png)
I tried to reading the cypress docs and searching on the internet, however the examples for solutions did not work. I am on on Electron version: 21.0.0, Bundled Node version:
16.16.0
I think you are mistaken about the results of your xpath expression.
You have used //div[5]/div[1]/input which can return multiple elements.
The // predicate will "select all" if they are present.
Only / predicate is guaranteed to return a single element.
Since Cypress is telling you it found multiple elements, it is more likely that your selector is wrong than the Cypress library.
You will have to change the xpath selector.
The answer is in your error message - you're trying to use cy.type() but the previous command (cy.xpath()) is yielding more than one element. I would focus on figuring out what differentiates the field you want to type in from the others found by cy.xpath(). If there is nothing different between them, then you can simply select the correct element by the 0-index of the element.
cy.xpath(element).eq(0).type(value); // assumes the first element yielded by cy.xpath
XPathError
message: "Invalid expression.
(string-join(/form/Data/MProcess/Process/Id/string(), ','))
I thought the problem was Process Id was not returning string so I tried string() and text() but they did not work. I can't find the solution.
Here is an example process id: aee865d1-7253-489c-8d53-2a0d580639d0
string-join() is an XPath 2.0 function, and many early XPath processors were never upgraded to 2.0. Check what XPath processor you are using and what language level it supports, and upgrade if you can.
In one of the API solution, incoming request is in XML format, and i need to fetch first child node tag name to make decision to run the logic. I am using xpath to get the tag name, when in am running xpath i am getting error "Can not convert #STRING to a NodeList"
I have tried with local-name and name, but both are giving same error.
my xml is as below
<p:Check xmlns:p="http://amarwayx.com.cu/WCSXMLSchema/creptonium">
<AttributeChnageLocal>
<TaskID>17723</TaskID>
<BatchID>12345</BatchID>
<Expiry>2022-12-06</Expiry>
<TimeStamp>2019-07-20T22:45:48</TimeStamp>
</AttributeChnageLocal>
</p:Check>
and Xpath i used are
local-name(/p:Check/*)
name(/p:Check/*)
local-name(/p:Check/*[1])
name(/p:Check/*[1])
how ever is some online xpath evaluator has evaluated correct name(AttributeChnageLocal), i am not getting where the xpath syntax is wrong.
below is my tool snapshot.
same kind of expression works fine
You have ticked a box labelled "store the string value of the selected node as text", which suggests that the XPath evaluation tool you are using expects your XPath expression to select a node; but it doesn't, it selects a string.
I don't know what this tool you are using is, but unfortunately all its options seem to assume that you are selecting nodes.
With VTD-XML, is it possible to execute the following XPath statement?
if(10 > 5) then "yes" else "no"`
I have a much more complex statement, but it will not run with my current setup. There are these methods possible: evalXPathToBoolean(), evalXPathToNumber(), and evalXpathToString(). But, I am receiving this error when trying to execute:
com.ximpleware.extended.XPathParseExceptionHuge: XPath Syntax error: #8
autoPilot.selectXPath(xpath) // does not like this
while((i=autoPilot.evalXPath())!=-1){
list.add(vtdNav.toString(i));
}
This is valid XPath and works in XMLSpy. Is it possible to do this with VTD-XML? Please advise.
VTD-XML supports full set of XPath 1.0. The syntax you alluded to is likely XPath 2.0 syntax... which is not supported by VTD-XML at this point.
The solution/work-around is to take your conditional statement and code it into your application logic, and only use VTD-XML XPath boolean/number evaluation capability to obtain the values , which you can then weave into your condition logic...
I'm attempting to use the tokenize method in a SelectNodes(" ") call, to filter some things out.
I have something along the lines of:
<nodes>
<node colors="RED,BLUE,YELLOW"/>
</nodes>
And my xpath is as such:
nodes/node[not(empty(tokenize("GREEN,YELLOW,PURPLE", ",") intersect tokenize(#colors, ",")))]
Simply, I've got two comma delimited list, one as an attribute, and one as a "filter" for the attributes. I want to select all nodes where #colors contains, somewhere, one of the words inside of "GREEN,YELLOW,PURPLE".
I thought I had the solution for it with that XPath, but it seems either:
A: I did something wrong, or
B: The version of XML DOM document I am using does not support tokenize()
The XPath above, in a SelectNodes( ) call will throw up an error message, saying msxml3.dll: Unknown method.", then pointing to the tokenize() method.
I tried doing setProperty("SelectionLanguage", "XPath"), but that did not seem to solve the issue either.
Is there any way for me to perform an equivalent XPath selection, without resorting to a bunch of and contains(#colors, "GREEN") and contains(#colors, "YELLOW")...?
As JLRishe says, msxml does not support XPath 2.0.
Depending on the environment that you are in there is probably third-party software you can use that supports either XPath 2.0 or XQuery 1.0 (which is a superset of XPath 2.0).
Microsoft's XML software is getting very dated and there has been little new development for 10 years now. It's time to consider alternatives.