2012-10-24 32 views
2

選擇從一長串合格文本這裏是一塊XML文檔:如何在XPath的

<book category="WEB"> 
    <title lang="en">XQuery Kick Start</title> 
    <author>James McGovern</author> 
    <author>Per Bothner</author> 
    <author>Kurt Cagle</author> 
    <author>James Linn</author> 
    <author>Vaidyanathan Nagarajan</author> 
    <year>2003</year> 
    <price>49.99</price> 
</book>  

有人問我找出其姓氏開頭大寫字母「C」使用XPath的作者。這個問題很簡單,因爲只有一個限定條件,我可以在空格後面使用函數substring-after(),然後檢查它是否以「C」開頭。但也有可能這個傢伙有一個很長的名字,因此中間名可以出現,比如Kurt Van Persie Cagle。我怎樣才能去掉最後一個空白後的子字符串?

請解釋並使用XPath中的函數。

+0

什麼您正在使用XPath版本? –

+0

我認爲這是XPath 1.0 @KirillPolishchuk –

回答

0

可以使用「的混亂」的XPath,例如你有4個字的限制在author

//author[ 
    (starts-with(substring-after(., ' '), 'C') and not(contains(substring-after(., ' '), ' '))) 
    or 
    (starts-with(substring-after(substring-after(., ' '), ' '), 'C') and not(contains(substring-after(substring-after(., ' '), ' '), ' '))) 
    or 
    (starts-with(substring-after(substring-after(substring-after(., ' '), ' '), ' '), 'C') and not(contains(substring-after(substring-after(substring-after(., ' '), ' '), ' '), ' '))) 
] 

輸入:

<book> 
    <author>James McGovern</author> 
    <author>Per Bothner</author> 
    <author>Kurt Cagle</author> 
    <author>James Linn</author> 
    <author>James Linn</author> 
    <author>Kurt Van Persie Cagle</author> 
</book> 

以上的XPath將選擇2名作者:Kurt CagleKurt Van Persie Cagle。您可以擴展此XPath以匹配具有5個單詞的作者,例如... :)

+0

我已閱讀您的解決方案,我認爲它只是使用XPath 1.0解決了問題。非常感謝你!但是,如果使用皇家名稱,中間名稱可能會變得很長,導致XPath 1.0表達式中繁瑣的嵌套結構。使用XSLT 2.0似乎可以解決問題,我將在下一章中學習。 :D –

+0

@魏上鬆,不客氣! –

0

我被要求用XPath找到姓氏以大寫字母 「C」開頭的作者。

一般來說,這是不可能選擇一個XPath 1.0表達式。當然,這可以使用XSLT 1.0來完成。

在XPath 2.0

/*/author[starts-with(tokenize(., ' ')[last()], 'C')] 

XSLT 2.0 - 基於驗證

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:sequence select="/*/author[starts-with(tokenize(., ' ')[last()], 'C')]"/> 
</xsl:template> 
</xsl:stylesheet> 

當在下面的XML文檔被應用於這種轉變:

<book category="WEB"> 
    <title lang="en">XQuery Kick Start</title> 
    <author>James McGovern</author> 
    <author>Per Bothner</author> 
    <author>Kurt van Persy Cantor Bagle</author> 
    <author>Kurt van Persy Cantor Cagle</author> 
    <author>James Linn</author> 
    <author>Vaidyanathan Nagarajan</author> 
    <year>2003</year> 
    <price>49.99</price> 
</book> 

XPath表達式求值和所選擇的(多個)節點被複制到輸出:

<author>Kurt van Persy Cantor Cagle</author> 
+0

感謝您的解決方案!我還沒有學習XSLT,也沒有學習XPath 2.0中的tokenize()。但你的解決方案看起來更整潔。我目前正在學習XML基礎知識。稍後我會回到您的解決方案。 :D –

0

繼續使用@DimitreNovatchev提供的出色解決方案時,請注意,如果您的解析器具有該屬性,則可以在XSLT 1.0中使用相同的標記化概念使用EXSLT's string extension functions的能力。

例如,這使能EXSLT-XSLT 1.0溶液:

<?xml version="1.0"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:str="http://exslt.org/strings" 
    exclude-result-prefixes="str" 
    version="1.0"> 
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
    <xsl:copy-of 
     select="/*/author[starts-with(str:tokenize(., ' ')[last()], 'C')]" /> 
    </xsl:template> 

</xsl:stylesheet> 

...產生當施加到@ Dimitre的修改的輸入XML相同的期望結果:

<author>Kurt van Persy Cantor Cagle</author>