首页 > 解决方案 > 为什么这个 XPath 表达式适用于一个节点而不适用于另一个节点?

问题描述

我有一个函数可以检索.InnerTextXML 节点中的属性:

    string getPropertyFromNode_string(XmlNode node, string propertyName)
    {
        try
        {
            string selectString = "./empty:content/m:properties/d:";
            return node.SelectSingleNode(selectString + propertyName, Utils.nmREST).InnerText;
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception.Message);
            throw exception;
        }
    }

nmREST在静态类的构造函数中定义Utils如下:

    public static XmlNamespaceManager nmREST = new XmlNamespaceManager(new NameTable());

    static Utils()
    {
        nmREST.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
        nmREST.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
        nmREST.AddNamespace("empty", "http://www.w3.org/2005/Atom");
        nmREST.AddNamespace("z", "#RowsetSchema");
    }

我在这个 XmlNode 上测试函数:

<entry m:etag="&quot;81&quot;" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
    <id>Web/Lists(guid'someguid')/Items(1213)</id>
    <category term="SP.Data.LibItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <link rel="edit" href="Web/Lists(guid'someguid')/Items(1213)" />
    <title />
    <updated>2019-04-16T06:16:50Z</updated>
    <author>
        <name />
    </author>
    <content type="application/xml">
        <m:properties>
            <d:Id m:type="Edm.Int32" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">1213</d:Id>
            <d:FileLeafRef xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">myfile.xlsm</d:FileLeafRef>
            <d:FeatureCount m:type="Edm.Double" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">33</d:FeatureCount>
            <d:Status xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">Production Ready</d:Status>
            <d:CheckoutUserId m:null="true" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" />
            <d:EditorId m:type="Edm.Int32" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">25</d:EditorId>
            <d:ID m:type="Edm.Int32" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">1213</d:ID>
        </m:properties>
    </content>
</entry>

使用此函数调用:

getPropertyFromNode_string(thisNode,"ID")

1213并且成功检索到该值。

但是,当我在以下 XmlNode 上对其进行测试时:

<entry m:etag="&quot;24&quot;" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
    <id>Web/Lists(guid'someguid')/Items(1422)</id>
    <category term="SP.Data.LibItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <link rel="edit" href="Web/Lists(guid'someguid')/Items(1422)" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Station" type="application/atom+xml;type=entry" title="Station" href="Web/Lists(guid'someguid')/Items(1422)/Station">
        <m:inline>
            <entry>
                <id>anotherguid</id>
                <category term="SP.Data.DifferentLibItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
                <title />
                <updated>2019-04-16T05:58:17Z</updated>
                <author>
                    <name />
                </author>
                <content type="application/xml">
                    <m:properties>
                        <d:FacilityNumber xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">1068</d:FacilityNumber>
                    </m:properties>
                </content>
            </entry>
        </m:inline>
    </link>
    <title />
    <updated>2019-04-16T05:58:17Z</updated>
    <author>
        <name />
    </author>
    <content type="application/xml">
        <m:properties>
            <d:FileLeafRef xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">thatfilename.xlsm</d:FileLeafRef>
            <d:Title m:null="true" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" />
        </m:properties>
    </content>
</entry>

使用函数调用:

getPropertyFromNode_string(thisNode,"FacilityNumber")

然后SelectSingleNode()调用会引发异常并显示以下消息:

Object reference not set to an instance of an object.

我猜这意味着 XPath 表达式没有成功定位<d:FacilityNumber>元素,所以没有对象可以获取InnerText。为什么找不到元素?第二个节点的 XML 结构有什么不同,我应该改用什么 XPath 表达式?

标签: c#xmlxpath

解决方案


根据 Laurent Lequenne 对 OP 的评论,包括 XPath 表达式中子节点的完整嵌套序列成功检索到所需的子节点,如下所示:

./empty:link/m:inline/empty:entry/empty:content/m:properties/d:

推荐阅读