XQuery/XPath с Saxon API - нужны регистрозависимые пути
Проще говоря, я бы хотел, чтобы все приведенные ниже пути имели одинаковые значения:
- / Корень / элемент1/ текст ()
- / ROOT / ITEM1/ текст ()
- / Root / Элемент1/ текст ()
Насколько я понимаю, идея состоит в том, что узлы XML с разными регистрами фактически рассматриваются как разные. Проблема здесь в том, что я строю динамический сборщик XML на основе набора реляционных таблиц SQL DB. Это приложение будет установлено на более чем 50 различных серверах с собственными экземплярами SQL. 50% структуры таблиц, имен и типов будут отличаться, тогда как остальные 50% МОГУТ отличаться в буквенном регистре имени. Цель состоит в том, чтобы применить стандартные преобразования XQuery к этим динамически генерируемым XML-файлам, имеющим пользовательский И стандартный раздел, что означает, что оно применимо ко ВСЕМ 50+ серверам. Вот почему я ищу логику пути без учета регистра, несмотря на то, что она идет вразрез с основами XML, это дало бы ОГРОМНОЕ преимущество для нашего варианта использования, чтобы "выбрать" такую возможность.
Полезный обходной путь, который я сейчас использую для тестирования, - это предварительное преобразование с использованием XSLT для преобразования ВСЕХ имен узлов элемента в нижний регистр. Так что, если из этого ничего не выйдет, то, по крайней мере, все равно будет достаточно работоспособным
Я новичок в XQuery/XPath/XSLT, поэтому пространства имен для меня все еще странная концепция. Одна вещь, на которую я наткнулся, это объявление сличения. Однако я не могу сказать, если это только для типичных сравнений строк ($x = $y) или других подобных вещей. Saxon имеет встроенный метод своего процессора под названием Processor.DeclareCollation(), я пытался его использовать, однако я не заметил, что запросы выполняются по-другому.
Является ли сопоставление моим ответом и просто вопросом того, как его настроить (до этого никогда не путался)? Есть ли другой способ пойти по этому поводу? Или я должен придерживаться имеющегося у меня решения?
* PS Наличие нечувствительных к регистру имен функций также было бы потрясающим бонусом [text() против TEXT()] НО я могу жить без этого, просто было бы полезно, чтобы нублеты в моей команде испытывали меньше ошибок.:)
2 ответа
Этот XPath,
/*[lower-case(name()) = "root"]/*[lower-case(name()) = "item1"]/text()
будет охватывать ваши примеры без учета регистра.
Заметки:
- Пожалуйста, не делай этого. XML чувствителен к регистру при разработке и стандартизации.
- Нет, не существует глобального способа объявления нечувствительности к регистру. Смотрите № 1.
- Нет, стандарт не должен уступать уникальным проектам; уникальные проекты должны уступить этому.
XML изначально чувствителен к регистру. Мой обычный совет при написании преобразования, которое должно обрабатывать различные форматы ввода, - записать их в виде конвейера, в котором первый этап избавляет от ненужных изменений, чтобы фаза "бизнес-логики" могла сосредоточиться на одной задаче, не отвлекая других входные представления.
По сути, это решение, предложенное @MadsHansen.
Другой способ сделать это (на саксонском языке) может быть аккуратным, хотя и немного сложным: вы можете реализовать собственную модель дерева, в которой имена элементов и атрибутов представлены в нормализованном регистре, скрывая любые варианты регистра в базовых данных. В Saxon имеется множество механизмов для реализации пользовательских моделей деревьев в качестве оберток над другими моделями деревьев, поэтому на самом деле это не будет большой объем кода; но знакомство с внутренностями Саксонии достаточно, чтобы заставить его работать, было бы серьезной проблемой.
Однако мой реальный совет - не начинать отсюда. То, как вы создали словарь XML, неверно. В XML "Straße" и "STRASSE" - это разные имена, и все инструменты XML будут рассматривать их как разные имена, и если вы хотите рассматривать их как альтернативные способы написания одного и того же имени, то вы идете против естественного поток, и это всегда увеличивает сложность и затраты.
В XPath параметры сортировки полезны для сравнения пользовательских данных: можно использовать параметры сортировки, в которых строки "Straße" и "STRASSE" считаются эквивалентными, когда они появляются в текстовом содержимом элементов и атрибутов. Но они никогда не используются при сравнении имен элементов и атрибутов.