代码之家  ›  专栏  ›  技术社区  ›  Polyfun MicBehrens

如何在SelectSingleNode中使用fn:max

  •  4
  • Polyfun MicBehrens  · 技术社区  · 14 年前

    当我运行时:

    XmlDocument xmlResponse = new XmlDocument();
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlResponse.NameTable);
    nsmgr.AddNamespace("fn", " http://www.w3.org/2005/xpath-functions");
    
    xmlResponse.LoadXml(
        "<LIST>" + 
            "<ITEM NUMBER='3' TEXT='C'/>" + 
            "<ITEM NUMBER='2' TEXT='B'/>" + 
            "<ITEM NUMBER='1' TEXT='A'/>" + 
        "</LIST>");
    
    XmlNode xmlNode = xmlResponse.SelectSingleNode("//ITEM[fn:max(@NUMBER)]", nsmgr);
    

    我在最后一行得到一个异常“XsltContext是这个查询所需要的,因为有一个未知函数。”。我正在尝试选择具有最高NUMBER属性的ITEM元素。这是否可以使用XPATH?

    谢谢

    3 回复  |  直到 14 年前
        1
  •  4
  •   abatishchev Marc Gravell    11 年前
    XmlNode xmlNode = xmlResponse.SelectSingleNode("//ITEM[fn:max(@NUMBER)]", nsmgr);
    

    max() 是XPath 2.0函数。NET仅支持XPath1.0。

    /*/ITEM[not(@NUMBER > ../@NUMBER)]
    

    即使.NET实现了XPath2.0,问题中的XPath表达式也不会选择 ITEM NUMBER 属性。使用 最大值()

    /*/ITEM[xs:integer(@NUMBER) eq max(../@NUMBER/xs:string(.))]
    

    最大值() 必须是我们需要确定最大元素的项目序列。相反,在问题的XPath表达式中:

    //ITEM[fn:max(@NUMBER)]
    

    max 只有一个参数 上下文节点的属性。因此,上述等同于:

    //ITEM[@NUMBER]
    

    项目 具有 数字 属性。

        2
  •  2
  •   Bharath K    14 年前

    可以使用以下机制查找任何给定属性值最高的节点:

    XmlNode xmlNode = xmlResponse.SelectSingleNode( "//ITEM[not(preceding-sibling::ITEM/@NUMBER > @NUMBER or following-sibling::ITEM/@NUMBER > @NUMBER)]", nsmgr ); 
    

    在XPath中,可以实现自己的XsltContext并将其传递给XPathExpression.SetContext()方法。

        3
  •  1
  •   abatishchev Marc Gravell    11 年前

    但是,要查找具有最大值的元素,Microsoft API还有另一种可能的解决方案,即排序(按降序排列最大值)和按排序顺序访问第一个项:

    XmlDocument xmlResponse = new XmlDocument();
    xmlResponse.LoadXml(
            "<LIST>" +
                "<ITEM NUMBER='3' TEXT='C'/>" +
                "<ITEM NUMBER='2' TEXT='B'/>" +
                "<ITEM NUMBER='1' TEXT='A'/>" +
            "</LIST>");
    
    XPathNavigator nav = xmlResponse.CreateNavigator();
    XPathExpression exp = nav.Compile("LIST/ITEM");
    exp.AddSort("@NUMBER", XmlSortOrder.Descending, XmlCaseOrder.None, "", XmlDataType.Number);
    XmlNode item = nav.SelectSingleNode(exp).UnderlyingObject as XmlNode;
    Console.WriteLine(item.OuterXml);