【问题标题】:How do I use the translate function in a predicate of a XPath argument to XmlDocument.SelectNodes?如何在 XmlDocument.SelectNodes 的 XPath 参数的谓词中使用 translate 函数?
【发布时间】:2010-08-19 00:13:47
【问题描述】:

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

鉴于下面的 XML,我想获得一个 XMLNodeList<user> 节点,其中 <role> 是“管理员”。

<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);

但是,我没有取回任何节点。有人可以告诉我我做错了什么吗?

【问题讨论】:

  • 顺便说一句,C# 与您的问题并不真正相关。这是一个 .NET 2.0 的问题,而你恰好在用 C# 编程。
  • 当您尝试使用您的代码调用translate 时会发生什么?表面上看起来还不错。

标签: c# .net xpath predicate translate


【解决方案1】:

_document.SelectNodes("//users/user[roles[translate(role,'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 子元素,并且&lt;role&gt;admin&lt;/role&gt; 元素不是其父元素的第一个role 子元素,XPath 表达式将不会选择所需元素。

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

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

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

更新:@ck 现在提供了他的真实 XML 文档,事实上,在真实的 XML 文档中,role 子级(&lt;role&gt;admin&lt;/role&gt; 元素)并不是第一个role 父母的孩子。

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

【讨论】:

  • 谢谢。你击中了要害。我已经编辑了这个问题,以反映我试图更仔细地解析的实际 XML。但是,我确实有类似的问题。我会单独发布。
猜你喜欢
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多