Я поддерживаю устаревший инструмент компании, в которой я работаю, написанный на C#, и я конвертирую его в стандарт .Net 2.0. Он использует процессор Саксон-ОН для обработки некоторых XPath и замены некоторых конфигураций в файлах. Его NuGet-пакет на .NET имеет зависимости, которые не позволяют выполнять его на всех платформах, совместимых со стандартом .Net 2.0 (в моем случае и на .Net Framework, и на .Net core), поэтому мне нужно заменить его одним другим инструментом, лучше, если стандартная библиотека .Net XPath.
Проблема в том, что инструмент использует некоторые XPath, которые выполняют сложные операции, такие как объединение строк и выбор элемента массива, и я не знаю, является ли это специфичным для Saxon синтаксисом или относится к стандарту.
Это важно знать, потому что, если XPath соответствуют какому-то стандарту XPath, я мог бы найти другой способ обработки тех же XPath.
Вот несколько примеров:
Первый:
for $row in /Item/SubItem[*]/SubSubItem return(concat($row, \"/ConcatValue\"))
Второй:
/Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(), '')[1]
Знаете ли вы что-нибудь об этом синтаксисе XPath?
Спасибо
Прав ли я, думая, что, когда вы говорите: «Его пакет NuGet не соответствует стандарту .Net», вы имеете в виду, что Saxon на .NET имеет зависимости, которые означают, что он не будет работать на всех совместимых платформах, в частности, что он не будет работать на .NET Core»? Потому что то, как вы это сформулировали, звучит так, как будто с пакетом NuGet что-то не так, что легко исправить.
@MichaelKay да, мне нужно, чтобы это приложение работало как в среде .Net, так и в основных средах .Net, поэтому все используемые зависимости должны соответствовать стандарту .Net 2.0, чтобы быть исполняемым «все». Извините за некорректную формулировку, сейчас исправлю
Выражения XPath, которые вы привели в качестве примеров, требуют процессора XPath 2.0, но они не являются специфическими для Saxon.
Выражение
for $row in /Item/SubItem[*]/SubSubItem return(concat($row, \"/ConcatValue\"))
является ForExpression
, специфичным для XPath 2.0, и его нелегко преобразовать в XPath 1.0, поскольку его результатом является последовательность строк, а в XPath 1.0 нет такого типа данных.
Выражение
/Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(), '')[1]
специфичен для XPath 2.0, поскольку использует выражение в скобках в правой части оператора "/"; и снова, потому что он возвращает последовательность строк.
Боюсь, я не могу посоветовать вам, существуют ли библиотеки XPath 2.0, которые работают на .NET Core, что, как я полагаю, является вашим требованием. Saxon нельзя заставить работать на .NET Core из-за его зависимости от IKVM, который не поддерживает эту платформу и который (как я понимаю) не может быть легко адаптирован для этого.
Обратите внимание, что XPath 2.0 является подмножеством XQuery 1.0, поэтому вы можете распространить поиск как на процессоры XQuery 1.0, так и на процессоры XPath 2.0.
Благодаря комментарию это я смог протестировать XPath2.Net, и теперь все работает. Мне нужно было изменить только один тип определения XPath
Этот:
/Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(), '')[1]
Изменения к
/Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(.), '')[1]
Обратите внимание на дополнительный точечный аргумент функции string()
.
Это странно, поскольку точка не должна требоваться; на самом деле, согласно стандартный
In the zero-argument version of the function, $arg defaults to the context item. That is, calling fn:string() is equivalent to calling fn:string(.)
но XPath2 жалуется на эту ошибку
{"The function 'string'/0 was not found in namespace 'http://www.w3.org/2003/11/xpath-functions'"}
ОБНОВИТЬ:
После обновления библиотеки XPath2.Net до версии 1.0.8 синтаксис string()
работает.
Также немного беспокоит то, что он дает URI пространства имен как http://www.w3.org/2003/11/xpath-functions
, поскольку это не то пространство имен, которое используется в окончательной версии спецификации.
Что касается вызова аргумента с нулевой строкой, я зарегистрировал проблему с потенциальным исправлением в github.com/StefH/XPath2.Net/issues/23, поэтому, возможно, вы увидите новый выпуск, устраняющий эту проблему.
Я могу подтвердить, что с последним обновлением библиотеки XPath2 (1.0.8) синтаксис string() работает должным образом. Я обновляю ответ соответственно
Пожалуйста, ознакомьтесь с соответствующими спецификациями XPath, на которые для вас удобно ссылаться, на SO-странице stackoverflow.com/tags/xpath-3.1/info тега, который вы использовали. И я не знаю, кто бы подумал об использовании
concat
«сложной» операции в XPath.