Как применить функцию XPath подстроку-после '
Что такое выражение XPath, которое я бы использовал, чтобы получить строку, следующую за "HarryPotter:" для каждой книги.
т. Учитывая этот XML:
<bookstore>
<book>
HarryPotter:Chamber of Secrets
</book>
<book>
HarryPotter:Prisoners in Azkabahn
</book>
</bookstore>
Я бы вернулся:
Chamber of Secrets
Prisoners in Azkabahn
Я пробовал что-то вроде этого:
/bookstore/book/text()[substring-after(. , 'HarryPotter:')]
Я думаю, что мой синтаксис неверен...
Ответы
Ответ 1
В XPath 2.0 это может быть выражено одним выражением XPath:
/*/*/substring-after(., 'HarryPotter:')
Здесь мы используем очень мощную функцию XPath 2.0, которая в конце пути шагов местоположения может поместить функцию, и эта функция будет применена ко всем узлам в текущем наборе результатов.
В XPath 1.0 нет такой функции, и это невозможно выполнить в одном выражении XPath.
Мы могли бы выполнить преобразование XSLT следующим образом:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="/*/*[substring-after(., 'HarryPotter:')]">
<xsl:value-of select=
"substring-after(., 'HarryPotter:')"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
При применении к исходному XML-документу:
<bookstore>
<book> HarryPotter:Chamber of Secrets </book>
<book> HarryPotter:Prisoners in Azkabahn </book>
</bookstore>
это преобразование дает желаемый результат:
Палата тайн
Заключенные в Азкабане
Ответ 2
В вашем XML у вас нет места между Гарри Поттером, но в вашем XQuery у вас есть место. Просто сравните его и престо, вы получите данные обратно...
Dim xml = <bookstore>
<book>HarryPotter:Chamber of Secrets</book>
<book>HarryPotter:Prisoners in Azkabahn</book>
<book>MyDummyBook:Dummy Title</book>
</bookstore>
Dim xdoc As New Xml.XmlDocument
xdoc.LoadXml(xml.ToString)
Dim Nodes = xdoc.SelectNodes("/bookstore/book/text()[substring-after(., 'HarryPotter:')]")
Dim Iter = Nodes.GetEnumerator()
While Iter.MoveNext
With DirectCast(Iter.Current, Xml.XmlNode).Value
Console.WriteLine(.Substring(.IndexOf(":") + 1))
End With
End While
Ответ 3
Выражение XPath
/bookstore/book/text()[substring-after(. , 'HarryPotter:')]
вернет набор node со всеми текстовыми узлами, содержащими значение "HarryPotter:". Чтобы получить название книги с последующим "HarryPotter:", вам нужно пройти этот набор node и получить эту подстроку для каждого node. Это можно сделать с помощью подстроки-после, если вы используете XSLT или с подстрокой и IndexOf, если вы используете VB, как показано балабастером.
Ответ 4
Xpath:
substring-after(//book, 'Advertised:')
Я совершенно новый в этой области, но для меня это работает...!