Как бороться с наличием или отсутствием пространств имен XML с помощью xslt - PullRequest
3 голосов
/ 16 апреля 2010

У меня есть несколько документов XML / TEI, и я пишу XSLT 2.0 для извлечения их содержимого.

Почти все документы TEI не имеют пространства имен, но один имеет пространство имен по умолчанию (xmlns="http://www.tei-c.org/ns/1.0"). Таким образом, все документы имеют один и тот же аспект с необъясненными тегами, такими как <TEI> или <teiHeader>, но если я пытаюсь извлечь содержимое, все работает с «non-namespaced-documents», но ничего (конечно) не извлекается из пространство имен-документ.

Итак, я использовал атрибут xpath-default-namespace="http://www.tei-c.org/ns/1.0", и теперь (конечно) единственный работающий документ - это пространство имен.

Я вообще не могу редактировать документы, поэтому я спрашиваю, есть ли способ динамически изменять пространство имен xpath-default-name, чтобы заставить работать xpath вроде //teiHeader как с документами с пространством имен, так и с документами без пространства имен

Ответы [ 3 ]

1 голос
/ 16 апреля 2010

Это ужасно, но это дает вам то, что вы хотите :

//*[name()='teiHeader']

Если вы используете этот стиль для всех шагов расположения в любом выражении XPath, выражения XPath будут выбирать элементы только по имени , независимо от того, принадлежат ли элементы какому-либо пространству имен.

1 голос
/ 17 апреля 2010

Если вы используете XSLT 2.0 , то у вас есть опция для подстановочного совпадения для пространства имен в тесте узла.

например. //*:teiHeader

http://www.w3.org/TR/xpath20/#node-tests

Тест узла также может иметь вид *: NCName. В этом случае проверка узла выполняется для любого узла главного вид узла оси шага, локальный имя соответствует данному NCName, независимо от его пространства имен или отсутствия пространство имен.

Это функционально эквивалентно примеру Дмитрия Новатчева, но немного короче / проще для ввода.

Однако это будет работать только в XSLT / XPATH 2.0 .

1 голос
/ 16 апреля 2010

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

Есть хороший пример (в XSLT 1) этого в DocBook XSLT . Взгляните на html / docbook.xsl и common / stripns.xsl

По сути, вам необходимо присвоить результат выделения пространства имен переменной, а затем вызвать существующий шаблон (для не пространства имен), но выбрать переменную.

...