Почему это выражение XPath работает для одного узла, а не для другого? - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть функция, которая извлекает .InnerText для атрибута в узле XML:

    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 следует использовать вместо этого?

1 Ответ

0 голосов
/ 17 апреля 2019

Согласно комментарию Лорана Лекена к OP, включая полную последовательность вложений дочерних узлов в выражении XPath, успешно извлекает нужный дочерний узел, как показано ниже:

./empty:link/m:inline/empty:entry/empty:content/m:properties/d:
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...