BaseX: попытка переместить элементы между пространствами имен в средстве обновления XQuery

Я хотел бы нормализовать входной файл XSD, чтобы поместить xs: перед любыми элементами XSD без xs:, добавленного с помощью XQuery.

copy $c:=doc("test.xsd")
modify
(
  if($c/schema)
  then
  (
    for $item in $c//*
    where substring($item/text(), 1, 3) != "xs:"
    return rename node $item as concat("xs:", $item/text())
  )
  else ()
)
return $c

Выполнение этого xqy на входном XSD без префикса xs: возвращает входной файл без изменений. Я обновляю $c и возвращаю его. Так что же не так?

входной файл:

<?xml version="1.0"?>
<schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<element name="note" type="xs:string"/>

</schema>

ожидаемый результат:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="note" type="xs:string"/>

</xs:schema>

PS: Кажется, мой вопрос вызывает недоумение. Мне нужно присутствие xs:, потому что у меня есть другая программа обработки текста, которая обрабатывает только элементы с префиксом xs:.


person JACK M    schedule 15.01.2017    source источник
comment
То, что вы пытаетесь обновить, вовсе не текстовые узлы, а xs: не текстовый префикс, а псевдоним пространства имен. Таким образом, попытки сопоставить подстроки узлов text() не имеют никакого смысла.   -  person Charles Duffy    schedule 15.01.2017
comment
то есть то, что вы на самом деле пытаетесь сделать, с точки зрения семантики XML-документа (это уровень, на котором работает любой запрос BaseX), заменяет элементы в пространстве имен по умолчанию на элементы с похожими именами в пространстве имен http://www.w3.org/2001/XMLSchema.   -  person Charles Duffy    schedule 15.01.2017
comment
... на самом деле есть несколько ответов о том, как это сделать в XSLT - см. ie. stackoverflow.com/questions/9026224/ -- но я не могу вам помочь в XQUF.   -  person Charles Duffy    schedule 15.01.2017
comment
(хотя эти подходы могут дать полезные подсказки - глядя на стандарт XQUF, там тоже можно отключить пространства имен копирования).   -  person Charles Duffy    schedule 15.01.2017
comment
Кстати, если в вашем документе для пространства имен default просто установлено значение http://www.w3.org/2001/XMLSchema, вам не понадобятся префиксы xs: для всего.   -  person Charles Duffy    schedule 15.01.2017
comment
(Когда вы говорите о другом инструменте для обработки текста, вы имеете в виду инструмент для обработки текста или инструмент для обработки XML? Потому что, если это инструмент, соответствующий стандарту XML стандарт, он заботится только о том, является ли пространство имен http://www.w3.org/2001/XMLSchema, а не о том, попало ли оно туда через xmlns:ns="http://www.w3.org/2001/XMLSchema" и парный префикс xs: в элементе, или совершенно другим именем префикса, указывающим на одно и то же пространство имен, или набором пространств имен по умолчанию, как с xmlns="http://www.w3.org/2001/XMLSchema"; и если он не соответствует, возможно, вам не следует использовать его для XML).   -  person Charles Duffy    schedule 17.01.2017
comment
@CharlesDuffy Извините за поздний ответ. я в отпуске. Программа обработки текста не распознает синтаксис XML.   -  person JACK M    schedule 29.01.2017


Ответы (1)


Это должно работать (это очень похоже на ваш подход):

copy $doc := doc("test.xsd")
modify (
  if($doc/*:schema) then (
    for $item in $doc//*
    let $name := name($item)
    where not(starts-with($name, 'xs:'))
    let $new-name := xs:QName('xs:' || replace($name, '^.+:', ''))
    return rename node $item as $new-name
  )
  else ()
)
return $doc
person Christian Grün    schedule 17.01.2017