XPath: сбой при выборе узла без полномочий root - PullRequest
2 голосов
/ 02 сентября 2011

Я пытаюсь выбрать узлы, начиная с узлов, которые не являются корневыми узлами документов XML. Код следующий:

 foreach (XmlNode xmlIter in root.SelectNodes("/refentry/refsect1[@id='parameters']/variablelist/*")) {
    Parameter p = new Parameter();

    xmlNode = xmlIter.SelectSingleNode("varlistentry/term/parameter");
    p.Identifier = xmlNode.InnerText;

    xmlNode = xmlIter.SelectSingleNode("varlistentry/listitem");
    p.Documentation = xmlNode.InnerText;
}

XML-документ (здесь только фрагмент) выглядит следующим образом:

<refsect1 id="parameters"><title>Parameters</title>
    <variablelist>
    <varlistentry>
        <term><parameter>pipeline</parameter></term>
        <listitem>
        <para>

        </para>
        </listitem>
    </varlistentry>
    <varlistentry>
        <term><parameter>program</parameter></term>
        <listitem>
        <para>

        </para>
        </listitem>
    </varlistentry>
    </variablelist>
</refsect1>

Но приведенный выше код не работает: переменная xmlNode всегда равна нулю ... Что не так?

Ответы [ 2 ]

3 голосов
/ 02 сентября 2011

Ведущий «/» означает «начало в корне документа».Попробуйте просто:

xmlNode = xmlIter.SelectSingleNode("varlistentry/term/parameter");
p.Identifier = xmlNode.InnerText;

xmlNode = xmlIter.SelectSingleNode("varlistentry/term/listitem");
p.Documentation = xmlNode.InnerText;

(Если вы используете .NET 3.5 или более позднюю версию, я бы лично использовал LINQ to XML - я считаю, что это проще в использовании, чем XPath, но это другой вопрос. Я могупредоставьте эквивалентный код LINQ to XML, если хотите.)

РЕДАКТИРОВАТЬ: Понял.Ваш запрос [stuff]/variablelist/* уже поступает в узел varlistentry - вы пытаетесь найти другой узел varlistentry ниже .Если вместо этого вы выберете все элементы varlistentry, вам нужно будет найти только элементы term/parameter и listitem под этим varlistentry.

Это работает:

foreach (XmlNode xmlIter in doc.SelectNodes
         ("/refentry/refsect1[@id='parameters']/variablelist/varlistentry"))
{
    XmlNode xmlNode = xmlIter.SelectSingleNode("term/parameter");
    Console.WriteLine("Identifier = {0}", xmlNode.InnerText);

    xmlNode = xmlIter.SelectSingleNode("listitem");
    Console.WriteLine("Documentation = {0}", xmlNode.InnerText);
}

MindВам, вероятно, все еще стоит проверить, что xmlNode не равен NULL, прежде чем использовать его.

1 голос
/ 02 сентября 2011

//refentry/refsect1[@id='parameters']/variablelist дает вам все variablelist узлы, относящиеся к предыдущим 2 узлам, независимо от их положения в вашем XML-файле. Это, однако, не очень хорошо для вас, поэтому, если вам нужна какая-либо производительность, вы всегда должны начинать навигацию с корневого узла, который равен /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...