2012-12-10 28 views
1

XML文件看起來像的XPath轉換爲小寫不工作

<employees>  
<employee id='1'> 
    <Profile_Name>admin</Profile_Name> 
    <UserName>user</UserName> 
</employee> 

<employee id='2'> 
    <Profile_Name>Admin</Profile_Name> 
    <UserName>USER</UserName> 
</employee> 

<employee id='3'> 
    <Profile_Name>Adminnn</Profile_Name> 
    <UserName>userrrr</UserName> 
</employee> 

,這裏是我的XPath

  employees/employee 
        [not(Deleted)] 
         [Profile_Name[last()] 
          [translate(., 
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
            'abcdefghijklmnopqrstuvwxyz' 
            ) 
          ] 
          = 
          'admin'or 
          UserName[last()] 
            [translate(., 
               'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
               'abcdefghijklmnopqrstuvwxyz' 
              ) 
            ] 
           = 
           'user' 
         ] 

應該選擇那些沒有Deletedemployee元素和Profile_Name =管理員或UserName =用戶不知道profileName和用戶名的情況

它工作正常,但不考慮字符大小寫。

它應該id = 1和2

+0

請,*編輯*的問題,並提供:1)完整的(但短)的XML文檔; 2)必須選擇哪些節點。 3)選擇規則的解釋。 –

+0

@DimitreNovatchev:done –

+1

HebaEl-Fadly,我編輯了問題並格式化了XPath表達式,因此它現在可讀且易於理解。查看我的答案,瞭解我認爲選擇所需節點的XPath表達式。 –

回答

1

現在你有這樣的(正確的格式,使之可讀):

  /employees/employee 
        [not(Deleted)] 
         [Profile_Name[last()] 
          [translate(Profile_Name[last()], 
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
            'abcdefghijklmnopqrstuvwxyz' 
            ) 
          ] 
          = 
          'admin'or 
          UserName[last()] 
            [translate(., 
               'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
               'abcdefghijklmnopqrstuvwxyz' 
              ) 
            ] 
           = 
           'user' 
         ]"; 

這顯然是錯誤的 - 包含translate()密切的謂詞太早了。

也許你想要這個

 /employees/employee 
        [not(Deleted)] 
          [translate(Profile_Name[last()], 
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
            'abcdefghijklmnopqrstuvwxyz' 
            ) 
          = 
          'admin' 
         or 
          translate(UserName[last()], 
             'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
             'abcdefghijklmnopqrstuvwxyz' 
            ) 
          = 
          'user' 
          ] 

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:template match="/"> 
    <xsl:copy-of select= 
    "/employees/employee 
        [not(Deleted)] 
          [translate(Profile_Name[last()], 
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
            'abcdefghijklmnopqrstuvwxyz' 
            ) 
          = 
          'admin' 
         or 
          translate(UserName[last()], 
             'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
             'abcdefghijklmnopqrstuvwxyz' 
            ) 
          = 
          'user' 
         ]"/> 
</xsl:template> 
</xsl:stylesheet> 

當下面的XML文檔應用這種轉變(基於提供一個,但增加了更多employee元素以提供更多必要的測試案例):

<employees> 
    <employee id='1'> 
     <Profile_Name>admin</Profile_Name> 
     <UserName>user</UserName> 
    </employee> 
    <employee id='2'> 
     <Profile_Name>Admin</Profile_Name> 
     <UserName>USER</UserName> 
    </employee> 
    <employee id='3'> 
     <Deleted/> 
     <Profile_Name>Admin</Profile_Name> 
     <UserName>user</UserName> 
    </employee> 
    <employee id='4'> 
     <Profile_Name>Adminnn</Profile_Name> 
     <UserName>userrrr</UserName> 
    </employee> 
</employees> 

XPath表達式求值和該評價的結果被複制到輸出:

<employee id="1"> 
    <Profile_Name>admin</Profile_Name> 
    <UserName>user</UserName> 
</employee> 
<employee id="2"> 
    <Profile_Name>Admin</Profile_Name> 
    <UserName>USER</UserName> 
</employee> 
1

你得放錯了地方的翻譯返回employee。你的代碼生成的XPath表達式將測試類似

Profile_Name[last()][translate(.,'ABCDE...', 'abcde...')] = 'foo' 

也就是說,它會找到最後Profile_Name元素,檢查該元素具有非空值,然後比較值(例如Foo)字符串foo 。相反,你需要

translate(Profile_Name[last()],'ABCDE...', 'abcde...') = 'foo' 

做翻譯的價值,而不是原始的比較。將完整的表達應該是這樣的

var xpath = "/employees/employee[not(Deleted)][translate(Profile_Name[last()],'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='" + ProfileName.ToLower() + "' or translate(UserName[last()],'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='" + UserName.ToLower() + "']"; 
+0

我更新到 var xpath =「/ employees/employee [not(Deleted)] [translate([Profile_Name [last()],'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='」+ ProfileName.ToLower() +'']「 +」或[translate(UserName [last()],'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='「+ UserName.ToLower()+」']]「;'但它仍然沒有工作 –

+0

@ HebaEl-Fadly你仍然有太多的方括號。我編輯了我認爲應該是正確的表達方式。 –

0

.NET XSLT實現允許在樣式表編寫定製管理功能。爲小寫()也可以是:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:utils="urn:myExtension" exclude-result-prefixes="msxsl"> 

    <xsl:output method="xml" indent="yes"/> 

    <msxsl:script implements-prefix="utils" language="C#"> 
    <![CDATA[ 
     public string ToLower(string stringValue) 
     { 
     string result = String.Empty; 

     if(!String.IsNullOrEmpty(stringValue)) 
     { 
      result = stringValue.ToLower(); 
     } 

     return result; 
     } 
    ]]> 
    </msxsl:script> 

    <!-- using of our custom function --> 
    <lowercaseValue> 
    <xsl:value-of select="utils:ToLower($myParam)"/> 
    </lowercaseValue> 

假設,即可以是緩慢的,但仍是可接受的。

不要忘記啓用嵌入式腳本轉換支持:

// Create the XsltSettings object with script enabled. 
XsltSettings xsltSettings = new XsltSettings(false, true); 

XslCompiledTransform xslt = new XslCompiledTransform(); 

// Load stylesheet 
xslt.Load(xsltPath, xsltSettings, new XmlUrlResolver());