xml - XPath 等效于 current()

标签 xml xpath

如何引用从 XPath 中评估 XPath 的节点?

例如。:

<Root>
    <Foo>
        <Bar><Elem>X</Elem><Ref>1</Ref></Bar>
        <Bar><Elem>Y</Elem><Ref>2</Ref></Bar>
        <Ref>2</Ref>
    </Foo>

在节点上执行的 XPath= /Root/Foo/Ref :
var myNode = GetNodeRootFooRef();
var xpath = "../Bar[Ref=.]/Elem";
myNode.SelectSingleNode(xpath); // does not work, see below

不幸的是 .在条件引用中 Bar元素而不是原来的 Ref我在其上执行 XPath 的节点。如何从 XPath 中引用原始上下文节点?

最佳答案

您至少需要 XPath 2.0 才能使用单个纯 XPath 表达式来解决它:for $current in . return ../Bar[Ref=$current]/Elem .

Microsoft 不支持 XPath 2.0,但有第三方 XPath 2 实现可插入现有的 .NET 架构并提供扩展方法,例如XmlNode (需要 using Wmhelp.XPath2; 和 NuGet 包 https://www.nuget.org/packages/XPath2/1.0.2/ ):

            string xml = @"<Root>
    <Foo>
        <Bar><Elem>X</Elem><Ref>1</Ref></Bar>
        <Bar><Elem>Y</Elem><Ref>2</Ref></Bar>
        <Ref>2</Ref>
    </Foo>
</Root>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            XmlNode refEl = doc.SelectSingleNode("/Root/Foo/Ref");

            XmlNode elem = refEl.XPath2SelectSingleNode("for $current in . return ../Bar[Ref=$current]/Elem");

            Console.WriteLine(elem.OuterXml);

或者,您可以使用 XPath 3.0 或更高版本,使用单个纯 XPath 表达式,使用 let绑定(bind)变量:let $c := . return ../Bar[Ref=$c]/Elem .

如果您想在 .NET 框架中的 System.Xml 上使用它,那么您可以安装和使用 XmlPrime,它提供了扩展方法 (http://www.xmlprime.com/xmlprime/doc/4.0/using-xpath.htm#extension):
            string xml = @"<Root>
    <Foo>
        <Bar><Elem>X</Elem><Ref>1</Ref></Bar>
        <Bar><Elem>Y</Elem><Ref>2</Ref></Bar>
        <Ref>2</Ref>
    </Foo>
</Root>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            XmlNode refEl = doc.SelectSingleNode("/Root/Foo/Ref");

            XmlNode elem = refEl.XPathSelectSingleNode("let $c := . return ../Bar[Ref=$c]/Elem");

            Console.WriteLine(elem.OuterXml);

输出 <Elem>Y</Elem> .

如果您想在 .NET 框架 XPath API 中获得可变分辨率,那么 SelectSingleNode/SelectNodes 的第二个参数是 XmlNamespaceManager它是 XsltContext 的基类它有一个方法 ResolveVariable https://msdn.microsoft.com/en-us/library/system.xml.xsl.xsltcontext.resolvevariable(v=vs.110).aspx .有project on Codeplex实现 XsltContext public class DynamicContext : XsltContext 中的可变分辨率所以你可以使用它:
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(@"<Root>
    <Foo>
        <Bar><Elem>X</Elem><Ref>1</Ref></Bar>
        <Bar><Elem>Y</Elem><Ref>2</Ref></Bar>
        <Ref>2</Ref>
    </Foo>
</Root>");

            XmlNode refEl = doc.SelectSingleNode("Root/Foo/Ref");

            DynamicContext context = new DynamicContext();
            context.AddVariable("current", refEl);

            XmlNode elem = refEl.SelectSingleNode("../Bar[Ref = $current]/Elem", context);

            Console.WriteLine(elem.OuterXml);

请参阅 https://weblogs.asp.net/cazzu/30888 中的文档.

关于xml - XPath 等效于 current(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42032599/

相关文章:

c# - 以编程方式设置折线点(C#、vvvv/SVG-Library)

java - 如何将 java.util.Date 对象转换为 dateTime 规范表示的受限形式

perl - 如何使用XPath查询eXist?

xml - 使用xpath的数组位置

java - 使用 .split().tokenizeXML() 在 Camel 中分割 xml 文件?

xml - 如何对 XSLT/XPATH 中的一组节点进行不区分大小写的查找?

xpath - 在此XML文档中查找值的正确XPath查询是什么?

html - <br/> 之后文本的 XPath

python - 在 svg 内的路径中查找 XPath

javascript - 你如何在 javascript 中使用多个引号?