views:

59

answers:

1

I trying to parse a string in an XML node by using an XPath query which requires that I strip out a substring and read the remaining value. The substring may have a dynamic amount of whitespace before and after it before I can get to the value, so it would be helpful to have some sort of a indexOf function to use in the XPath. I'm trying to use substring-after, but there is a good chance the XPath is 1.0, which according to this post might make this more difficult to accomplish. The following is an example of the XML I am trying to parse:

<root>
   <myField>     StringToParse        7</myField>
</root>

I'm trying to get at the value 7 in the string, which would seem possible with some combination of substring-after and normalize-space. I'm not entirely sure I'm using it correctly because no matter which way I try to use it, the result is either a null value or the entire string, with the substring not removed.

The way I am able to return the entire value (the lesser of two evils) is: /myField[substring-after(.,'StringToParse')], which I would hope would return ' 7' Could anyone let me know I'm doing wrong with the syntax, or if there is an alternate method I should be using to accomplish what I want?

Thanks,

Mike

+1  A: 

The way I am able to return the entire value (the lesser of two evils) is: /myField[substring-after(.,'StringToParse')], which I would hope would return ' 7' Could anyone let me know I'm doing wrong

You are close, but there are at least two problems with the expression:

/myField[substring-after(.,'StringToParse')]

  1. myField is not the top element in the document and this expression requests that the top element be selected and that this element's name is myField. If evaluated against the provided XML document, no node would be selected, because the top element in the provided XML document is named root.

  2. The function call to substring-after() is inside a predicate. This means that the top node named myField is to be selected depending on the value of the call to substring-after(), converted to boolean. This is clearly what you want -- you dont want a node -- you want a string!

Solution:

substring-after(/*/myField, 'StringToParse')

evaluates to (without the quotes):

"        7"

A better solution may be:

normalize-space(substring-after(/*/myField, 'StringToParse'))

this evaluates to just:

"7"
Dimitre Novatchev
@Dimitre - this is how I imagined it would work, however this isn't working when I try it in any sort of online XPath tester. It just bombs out. In my live scenario, the query results in an empty string (probably a null value) This could be a result of how the XPath is processed in .net, which is the platform I am using to evaluate the query. I will do a little more testing and get back to you.
Mike C
@Mike: Then you haven'r shown us the real XML document. I suspect that it may have a default namespace and this is the most FAQ with a wellknown answer.
Dimitre Novatchev
@Dimitre - The real XML document is basically the same thing, but this XPath isn't being evaluated in XSL, it's actually being evaluated by the System.Xml.XmlNode.SelectSingleNode(string xPath) method in .net. I suspect this is where the problem is because that method returns an XmlNode and not a string. When I've tried this using the Xpath Query tool here http://www.xmlme.com/XpathTool.aspx the error it gives me when trying to evaluate this expression is "Expression must evaluate to a node-set"
Mike C
@Mike: Use XPathNavigator.Evaluate()
Dimitre Novatchev