Синтаксис NodeList.SelectSingleNode()

Возникают проблемы с получением NodeList.SelectSingleNode() для правильной работы. Мой XML выглядит так:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<inm:Results xmlns:inm="http://www.namespace.com/1.0">
    <inm:Recordset setCount="18254">
        <inm:Record setEntry="0">
            <!-- snip -->
            <inm:Image>fileName.jpg</inm:Image>
        </inm:Record>
    </inm:Recordset>
</inm:Results>

Данные представляют собой длинный ряд <inm:Record> записей.

Я открываю документ и получаю объект NodeList, основанный на "inm:Record". Это прекрасно работает.

XmlDocument xdoc = new XmlDocument();
xdoc.Load(openFileDialog1.FileName);
XmlNodeList xRecord = xdoc.GetElementsByTagName("inm:Record");

Я начинаю цикл по NodeList, используя цикл for. Прежде чем обрабатывать данную запись, я хочу проверить и проверить, <inm:Image> установлено. Я думал, что это будет очень просто сделать

string strImage = xRecord[i].SelectSingleNode("inm:Image").InnerText;

Я думаю: "Для XRecord, в котором я нахожусь, иди найди <inm:Image> значение... Но это не работает, поскольку я получаю исключение, говорящее, что мне нужен XmlNameSpaceManager. Итак, я попытался настроить это, но никогда не мог получить правильный синтаксис.

Может кто-нибудь показать мне, как использовать правильный синтаксис XmlNameSpaceManager в этом случае.

На данный момент я обошел эту проблему, просматривая все дочерние узлы для данного xRecord и проверяя тег, как только я зациклился на нем. Я хотел бы проверить это значение в первую очередь, чтобы увидеть, если мне нужно зациклить над этим <inm:Record> запись вообще.

4 ответа

Решение

Не нужно перебирать все элементы Record, просто используйте XPath, чтобы указать нужное подмножество:

XmlDocument xdoc = new XmlDocument();
xdoc.Load(openFileDialog1.FileName);
XmlNamespaceManager manager = new XmlNamespaceManager(xdoc.NameTable);
manager.AddNamespace("inm", "http://www.inmagic.com/webpublisher/query");
XmlNodeList nodes = xdoc.SelectNodes("/inm:Results/inm:Recordset/inm:Record[inm:Image != '']", manager);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable);
string strImage = xRecord[i].SelectSingleNode("inm:Image",nsMgr).InnerText; 

Должен сделать это.

Используя эту библиотеку Xml, вы можете получить все записи, имеющие дочерний элемент Image, с этим:

XElement root = XElement.Load(openFileDialog1.FileName);
XElement[] records = root.XPath("//Record[Image]").ToArray();

Если вы хотите быть уверены, что дочерний элемент Image содержит значение, это можно выразить так:

XElement[] records = root.XPath("//Record[Image != '']").ToArray();

Используя библиотеки LINQ to XML, вот пример для получения значения этого упомянутого узла:

XDocument doc = XDocument.Load(openFileDialog1.FileName);
List<XElement> docElements = doc.Elements().ToList();
XElement results = docElements.Elements().Where(
   ele => ele.Name.LocalName == "Results").First();
XElement firstRecord = results.Elements().Where(
   ele => ele.Name.LocalName == "Record").First();
XElement recordImage = firstRecord .Elements().Where(
   ele => ele.Name.LocalName == "Image").First();
string imageName = recordImage.Value;

Кроме того, кстати, использование венгерской нотации для языка с проверкой типов является излишним. Вам не нужно добавлять к строковым переменным str когда это всегда будет string,

Другие вопросы по тегам