如何在XmlDocument.SelectNodes的XPath参数的谓词中使用translate函数?

时间:2010-08-19 00:13:47

标签: c# .net xpath predicate translate

我正在使用C#和.NET 2.0。

鉴于下面的XML,我想获得XMLNodeList <user><role>为“admin”的节点。

<users>
    <user>
        <name>John Doe</name>
        <roles>
            <role>superadmin</role>
            <role>admin</role>
        </roles>
    </user>
    <user>
        <name>Jane Doe</name>
        <roles>
            <role>superadmin</role>
            <role>admin</role>
        </roles>
    </user>
    <user>
        <name>Rob Doe</name>
        <roles>
            <role>support</role>
        </roles>
    </user>
 </users>

假设roleName =“admin”。这有效,但区分大小写。

userNodesForRole = _document.SelectNodes("//users/user[roles[role='" + roleName + "']]");

我想以不区分大小写的方式做这件事。我知道我不能使用matches函数,因为.NET 2.0(可能更高?)不支持XPath 2.0。所以我这样做了:

// abc...xyz is the string literal of the entire alphabet, of course
userNodesForRole = _document.SelectNodes("//users/user[roles[translate(role,'abc..xyz','ABC...XYZ')='" + roleName.ToUpper() + "']]", _xmlNamespaceManager);

但是,我没有得到任何节点。有谁能告诉我我错了什么?

1 个答案:

答案 0 :(得分:1)

  

_document.SelectNodes( “//用户/用户[角色[翻译(作用, 'abc..xyz', 'ABC ...... XYZ')='”   + roleName.ToUpper()+“']]”,_ xmlNamespaceManager);

这将评估XPath表达式,如下所示:

  //users/user
           [roles
             [translate(role,
                        'abcdefghijklmnopqrstuvxyz',
                        'ABCDEFGHIJKLMNOPQRSTUVXYZ'
                        )
             =
              'ADMIN'
              ]
           ]

以及在提供的XML文档上评估上述XPath表达式

<users>
    <user>
        <name>John Doe</name>
        <roles>
            <role>admin</role>
        </roles>
    </user>
    <user>
        <name>Jane Doe</name>
        <roles>
            <role>admin</role>
        </roles>
    </user>
    <user>
        <name>Rob Doe</name>
        <roles>
            <role>support</role>
        </roles>
    </user>
 </users>

选择以下节点:

<user>
    <name>John Doe</name>
    <roles>
        <role>admin</role>
    </roles>
</user>

<user>
    <name>Jane Doe</name>
    <roles>
        <role>admin</role>
    </roles>
</user>

如果roles元素中包含多个role子元素且<role>admin</role>元素不是第一个role,则XPath表达式不会选择所需元素其父母的孩子。

即使在这种情况下,选择所需元素的XPath表达式也是;

  //users/user
           [roles/role
             [translate(.,
                        'abcdefghijklmnopqrstuvxyz',
                        'ABCDEFGHIJKLMNOPQRSTUVXYZ'
                        )
             =
              'ADMIN'
              ]
           ]

第一个表达式引发异常或未选择所需节点的原因可能有多种。要找出确切的原因,请打印构造的XPath表达式并在此处提供。

更新:@ck现在提供了他的真正的 XML文档,实际上,在真实的XML文档中提供了role个孩子(<role>admin</role>元素)不是他们父母的第一个role孩子。

所以我的猜测和解释 是正确的。