Проверьте, удовлетворяет ли XML заданному пользователем предикату.

Получено из объявления пространств имен в выражении XPath

Упрощенная задача:

  • Существует множество файлов XML различной структуры с пространствами имен.
  • Пользователь определяет несколько выражений в текстовой форме
  • Выражения применяются к каждому файлу XML, что дает результат: да или нет.

Какую технологию следует использовать для этой задачи в .NET 3.5 без использования сторонних библиотек?

Кандидаты:

  • XPath. Это не предпочтительный случай, поскольку нет простого способа указать пространства имен в выражении XPath.
  • ...

Обновление:

Я понял, что на самом деле вопрос таков: Есть ли способ, кроме XPath?

Schematron - единственное предложение на данный момент.


person Anthony Serdyukov    schedule 02.02.2011    source источник
comment
Я согласен с Dr. Кей: если вы подтверждаете существование узла, вам следует использовать известный инструмент проверки, такой как Schematron   -  person    schedule 02.02.2011


Ответы (3)


Ограничение «без использования сторонних библиотек» кажется странным: большинство людей в наши дни пытаются максимизировать повторное использование кода.

Без этих ограничений я бы сказал, что Schematron — это ответ. Он делает именно то, что вы ищете.

Также можно добиться того же эффекта, используя таблицу стилей XSLT для определения правил проверки, но в конечном итоге вам придется заново изобретать Schematron.

person Michael Kay    schedule 02.02.2011
comment
@ Майкл-Кей: Да, этот вопрос довольно странный. ОП рассказывает нам об оценке выражений XPath конечных пользователей, у которых нет возможности привязывать свои префиксы к пространствам имен, которые используются в документе; Кроме того, в документе повторно используются одни и те же префиксы с разными пространствами имен. OP не хочет, чтобы синтаксис, не зависящий от пространства имен, был слишком неудобным, и спрашивает, есть ли какое-либо другое решение. - person Dimitre Novatchev; 02.02.2011

Упрощенная задача:

• Существует множество XML-файлов различной структуры с пространствами имен.

• Пользователь определяет несколько предикатов в текстовой форме

• Предикаты применяются к каждому файлу XML, что дает результат: да или нет

Неясно, что означает слово предикаты в приведенном выше описании.

Я предполагаю, что это означает: выражения XPath, которые оцениваются как логические

Если это так, каждое такое отдельное выражение можно оценить, например, с помощью XPathNavigator.Evaluate(XPathExpression)

Проблема использования разными пользователями разных пространств имен требует централизованного решения. Один из подходов, который я рекомендую, состоит в том, чтобы создать и опубликовать центральный каталог префиксов пространств имен для сопоставлений пространств имен, чтобы авторы выражений могли использовать только префиксы из этого каталога. Все эти префиксы будут привязаны к соответствующим пространствам имен перед оценкой любого выражения XPath. Класс .NET XmlNamespaceManager очень подходит для этой цели. Пример использования XmlNamespaceManager вместе с XpathNavigator.Evaluate() и XPathNavigator.Select() можно найти здесь .

Очень важно: никогда не оценивайте строки, содержащие выражение XPath — это может привести к инъекция XPath. Всегда компилируйте строку (например, используя XPathExpression.Compile ()). Даже если такая дисциплина соблюдается, оценка предоставленного пользователем выражения XPath может привести к угрозам безопасности.

person Dimitre Novatchev    schedule 02.02.2011
comment
Как я уже упоминал, существует неудобство использования пространств имен в выражении XPath. Ищем другой подход. - person Anthony Serdyukov; 02.02.2011
comment
@Anton: Да, вы упомянули, что в документах есть пространства имен, однако это никоим образом не связано с последующими требованиями и кажется даже ненужным упоминать. Если это не так, вы должны четко указать это в своем вопросе. Нереально ожидать осмысленного ответа на неоднозначный вопрос. Пожалуйста, отредактируйте и определите лучше. - person Dimitre Novatchev; 02.02.2011
comment
@Anton - пространства имен НЕ ДОЛЖНЫ использоваться в выражениях XPATH. Можно использовать XPATH, не зависящий от пространства имен (например, /*[local-name()='foo']), или инвертировать проверки пространства имен внутри предиката, чтобы избежать необходимости регистрировать пространства имен (например, /*[local-name()='foo' and namespace-uri()='urn:bar']). не возможно. Вы даже можете попытаться реверс-инжиниринг - person Mads Hansen; 02.02.2011
comment
@Mads-Hansen: Ему сказали об этой возможности в ответах/комментариях к его предыдущему вопросу, но @Anton отклонил это как слишком сложное... - person Dimitre Novatchev; 02.02.2011

Если пространства имен являются «проблемой», вы всегда можете:

  1. Предварительно обработайте XML-файлы с помощью модифицированного преобразования удостоверений для создания XML-файла с узлами, которые не привязаны к определенному пространству имен.
  2. Затем сравните предоставленный пользователем XPATH с измененным XML.
  3. Вернуть результат

Обратите внимание, что, хотя это упрощает создание и оценку XPATH, это полностью обходит причину для пространств имен, и вы можете получить неоднозначные совпадения для элементов/атрибутов из другого пространства имен и вернуть неправильные результаты< /сильный>.

person Mads Hansen    schedule 02.02.2011
comment
Спасибо, но пространства имен важны в моем случае. - person Anthony Serdyukov; 03.02.2011