Delphi / MSXML: запросы XPath не выполняются - PullRequest
4 голосов
/ 05 октября 2009

Я загрузил документ XML, и теперь я хочу выполнить запрос XPath, чтобы выбрать определенное подмножество XML. XML это

<?xml version="1.0"?>
<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
      XML.</description>
   </book>
</catalog>

и процедура выглядит примерно так:

procedure RunXPathQuery(XML: IXMLDOMDocument2; Query: string);
begin

  XML.setProperty('SelectionLanguage', 'XPath');

  NodeListResult := XML.documentElement.selectNodes(Query));

  ShowMessage('Found (' + IntToStr(NodeListResult.length) + ') nodes.');

end;

Проблема заключается в следующем: когда я запускаю запрос XPath '/ catalog' для вышеуказанного XML, он возвращает (как и ожидалось) список узлов из 1 элемента. Тем не менее, если я удаляю :xsi из <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> и перезапустите запрос, возвращенный список узлов будет пуст. Если я удалю весь атрибут «xmlns», результирующий список узлов снова будет иметь 1 элемент.

Итак, мой вопрос заключается в следующем: что я могу сделать, чтобы исправить это, то есть как я могу заставить MSXML возвращать правильное количество экземпляров (при выполнении запроса XPath), независимо от пространства имен (или других атрибутов)?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 05 октября 2009

См. эту ссылку !

Когда вы используете <catalog xmlns='http://www.w3.org/2001/XMLSchema-instance'>, весь узел будет перемещен в другое (по умолчанию) пространство имен. Ваш XPath не ищет в этом другом пространстве имен, поэтому он не может найти никаких данных. С <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> вы просто объявляете xsi как другое пространство имен. Это будет другое пространство имен, чем пространство имен по умолчанию.

Я не могу проверить это прямо сейчас, но добавление чего-то как это может помочь:

XML.setProperty('SelectionNamespaces', 'xmlns=''http://www.w3.org/2001/XMLSchema-instance''');

Или, может быть, это не так. Как я уже сказал, сейчас я не могу это проверить.

2 голосов
/ 05 октября 2009

Разобрался. Похоже, что моя проблема была описана здесь и здесь (и, скорее всего, и в других местах).

У меня работает запрос / * [local-name () = 'catalog'].

1 голос
/ 05 октября 2009

Использование:

document.setProperty('SelectionNamespaces', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
0 голосов
/ 17 ноября 2011
/*[local-name()='catalog'] 

- это решение вашего вопроса. Но почему вы хотите игнорировать пространства имен? Они были введены, чтобы выразить что-то, например, различать разные типы каталогов. С помощью вашего запроса вы теперь можете выбрать содержимое любого каталога в мире, но я предполагаю, что вы можете обрабатывать только книги. Что произойдет, если вместо этого вы получите каталог винтов или автомобилей?

Упомянутое в префиксе (xsi) верно. Если вы удалите префикс, все элементы будут в этом пространстве имен (тогда это называется пространством имен по умолчанию). Но вы все равно можете с этим справиться.

В любом случае в своем коде дайте пространству имен префикс. Он даже не должен совпадать с оригинальным префиксом:

XML.setProperty('SelectionNamespaces', "xmlns:xyz='http://www.w3.org/2001/XMLSchema-instance'"); 

Второе - адаптировать запрос XPath. Тогда должно быть

/xyz:catalog

Оригинальный XML только объявляет пространство имен xsi, но никогда не использует его. В этом случае вы можете удалить его полностью. Если вы хотите использовать пространство имен и хотите, чтобы оно содержало префиксы, то переписайте свой XML в

<?xml version="1.0"?>
<xsi:catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <xsi:book id="bk101">
    <xsi:author>Gambardella, Matthew</xsi:author>
    <xsi:title>XML Developer's Guide</xsi:title>
    <xsi:genre>Computer</xsi:genre>
    <xsi:price>44.95</xsi:price>
    <xsi:publish_date>2000-10-01</xsi:publish_date>  
    <xsi:description>An in-depth look at creating applications with 
    XML.</xsi:description>
 </xsi:book>
</xsi:catalog>
...