2012-07-06 48 views
1

我必須做一個不區分大小寫的XML搜索。我寫了XPath表達式,它們工作正常,但是當我在XPath表達式中使用translate函數時,出現錯誤。下面是被做工精細的XPath表達式:在XPath中使用translate函數給出錯誤

string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
string lower = "abcdefghijklmnopqrstuvwxyz"; 

string xpath = "/data/item[AID/@iskey='true' and AID/text() = 'fep'][not(*[@iskey][local-name() != 'AID' ])]";  

string xpath1 = "/data/item[translate('Aid','" + upper + "','" + lower + "')]"; 

這裏是我的XML:

<?xml version="1.0" encoding="utf-8"?> 
<data> 
<item> 
<AID iskey="true">fep</AID> 
    <account>MS</account> 
    </item> 
</data> 

我要放置translate功能在第一XPath表達式是這樣的:

string xpath = "/data/item[translate('AID','" + upper + "','" + lower + "')/@iskey='true' and translate('AID','" + upper + "','" + lower + "')/text() = 'fep'][not(*[@iskey][local-name() != translate('aid','" + upper + "','" + lower + "') ])]"; 

當我這樣做時,我得到以下錯誤: 表達式必須評估爲一個節點集。

這個xpath對我來說工作正常。 string col =「AID」​​; string xpath =「/ data/item [col/@ iskey ='true'and col/text()='fep'] [not(* [@ iskey] [local-name()!='col']) ]「;

現在我的要求是col值可以是任何情況下的大寫或小寫,所以我想改變我的xpath,它返回給我結果,而不管在哪種情況下數據存在於xml中。 如果用戶提供援助或援助或aiD它返回給我的結果。

回答

1

該錯誤是由於這樣的事實:在你的XPath表達式,你有這樣的定位步驟:

item['aid'/@isKey = 'true' ...] 

的子表達式:

'aid'/@isKey 

在XPath中語法上是非法的,因爲/運算符的左側必須是節點集 - 在這裏它只是一個字符串。

你想擁有一個XPath表達式像這樣 - 不是一個你目前正在生成:

/data/item 
     [*[translate(name(), 'aid', 'AID') = 'AID']/@iskey='true' 
     and 
     *[translate(name(), 'aid', 'AID') = 'AID'] = 'fep' 
     ] 
      [not(*[@iskey] 
       [translate(name(), 'aid', 'AID') != 'AID'] 
      ) 
     ] 

XSLT - 基於驗證

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

<xsl:variable name="vLower" select="'aid'"/> 
<xsl:variable name="vUpper" select="'AID'"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy-of select= 
     "/data/item 
      [*[translate(name(), 'aid', 'AID') = 'AID']/@iskey='true' 
      and 
      *[translate(name(), 'aid', 'AID') = 'AID'] = 'fep' 
      ] 
       [not(*[@iskey] 
        [translate(name(), 'aid', 'AID') != 'AID'] 
       ) 
      ] 
     "/> 
</xsl:template> 
</xsl:stylesheet> 

當這轉換應用於提供的XML文檔:

<data> 
    <item> 
     <AID iskey="true">fep</AID> 
     <account>MS</account> 
    </item> 
</data> 

XPath表達式求值和所選擇的節點(只有一個在這種情況下)將被複制到輸出

<item> 
    <AID iskey="true">fep</AID> 
    <account>MS</account> 
</item> 

更新

的OP有困難理解本解。這是一個例子,表明該解決方案適用於字符串「aid」的任意大寫:

當上述轉換應用於XML文檔(包含任何大寫「aid」的元素名稱)時,如此:

<data> 
    <item> 
     <aId iskey="true">fep</aId> 
     <account>MS</account> 
    </item> 
</data> 

再次預期的結果是產生

<item> 
    <aId iskey="true">fep</aId> 
    <account>MS</account> 
</item> 

更新2

的OP還有不明白的解決方案,並聲稱,對於一個特定的XML文檔 - 提供如下 - 「我用你的表情返回null」

這裏是XML文檔中提供的輸出

<data> 
    <item> 
     <aId iskey="true">fep</aId> 
     <account>FG</account> 
    </item> 
</data> 

當同一XSLT驗證針對該文件運行,再次正確的元素被選中:在OP的評論

<item> 
    <aId iskey="true">fep</aId> 
    <account>FG</account> 
</item> 
+0

是的。你檢查這個表達式嗎?我仍然得到相同的錯誤 – 2012-07-06 16:57:28

+0

@WaqarJanjua:看到我更新的答案 - 這在XSLT中使用時可以正常工作。 – 2012-07-06 17:10:44

+0

是的,它的工作。但是有一個問題,你把翻譯功能等於'AID',這是固定的? 。它可以是aid或AiD或aID等,所以當我將它改爲'aid'時,表達式返回null。它希望它不區分大小寫。 – 2012-07-06 17:26:08

0

而不是使用translate()的,請嘗試使用聯合:(aid|AID)

新的XPath:

/data/item[(aid|AID)/@iskey='true' and (aid|AID)/text() = 'fep'][not(*[@iskey][local-name() != 'AID' and local-name() != 'aid'])] 
+0

它不是固定的,它可以是援助,aiD,AId,AiD等我希望不區分大小寫xpath。 – 2012-07-06 15:40:29