Изменение всех значений атрибутов элемента с помощью Xquery

Как изменить все требуемые значения атрибутов так, как это выражено в примерах XML с помощью Xquery?

Я использую базу данных Basex 7.6 Xquery и XML. Моя цель до сих пор заключалась в том, чтобы обрабатывать с его помощью файлы XML.

Эта структура у меня уже есть:

       <address ref="file1" title="title1">
        <address ref="file1.1" title="title1.1">
          <address ref="file1.1.1" title="title1.1.1"/>
        </address>
        <address ref="file1.2" title="title1.2">
          <address ref="file1.2.1" title="title1.2.1"/>
          <address ref="file1.2.2" title="title1.2.2">
            <address ref="file1.2.2.1" title="title1.2.2.1"/>
            <address ref="file1.2.2.2" title="title1.2.2.2"/>
          </address>
        </address>
      </address>
      <address ref="file2" title="title2"/>

Но мне нужно иметь следующее:

       <address ref="mydir/file1" title="title1">
        <address ref="mydir/file1.1" title="title1.1">
          <address ref="mydir/file1.1.1" title="title1.1.1"/>
        </address>
        <address ref="mydir/file1.2" title="title1.2">
          <address ref="mydir/file1.2.1" title="title1.2.1"/>
          <address ref="mydir/file1.2.2" title="title1.2.2">
            <address ref="mydir/file1.2.2.1" title="title1.2.2.1"/>
            <address ref="mydir/file1.2.2.2" title="title1.2.2.2"/>
          </address>
        </address>
      </address>
      <address ref="mydir/file2" title="title2"/>

Мне удалось изменить первый элемент так, как я хотел, но все еще не могу сделать это так, как это принимает движок Xquery.

Я изменил первый элемент этим фрагментом кода в BaseX 7.6 и не понял, как применить это ко всем элементам.

        copy $c :=
               (<address ref="file1" title="title1">
                    <address ref="file1.1" title="title1.1">
                      <address ref="file1.1.1" title="title1.1.1"/>
                    </address>
                    <address ref="file1.2" title="title1.2">
                      <address ref="file1.2.1" title="title1.2.1"/>
                      <address ref="file1.2.2" title="title1.2.2">
                        <address ref="file1.2.2.1" title="title1.2.2.1"/>
                        <address ref="file1.2.2.2" title="title1.2.2.2"/>
                      </address>
                    </address>
                  </address>
              (:<address ref="file2" title="title2"/> WHY IS THIS NOT BY THE WAY ACCEPTED?:)

                )
                modify (
                  replace value of node $c/@ref with concat('mydir/', $c/@ref)
                )
                return $c

Информацию о том, как я пытался решить эту проблему, можно найти здесь: http://docs.basex.org/wiki/XQuery_Update#Non-Updating_Expressions

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

Заранее спасибо!


person sailfish    schedule 31.05.2013    source источник


Ответы (1)


Это добавит mydir/ к каждому атрибуту ref в ваших XML-данных.

  copy $c := (<root>
      <address ref="file1" title="title1">
        <address ref="file1.1" title="title1.1">
          <address ref="file1.1.1" title="title1.1.1"/>
        </address>
        <address ref="file1.2" title="title1.2">
          <address ref="file1.2.1" title="title1.2.1"/>
          <address ref="file1.2.2" title="title1.2.2">
            <address ref="file1.2.2.1" title="title1.2.2.1"/>
            <address ref="file1.2.2.2" title="title1.2.2.2"/>
          </address>
        </address>
      </address>
      <address ref="file2" title="title2"/>
      </root>)
  modify (
    for $e in $c//@ref
    return replace value of node $e with concat('mydir/', $e)
  )
  return $c

Второй узел address не работает, потому что в XML у вас должен быть ровно один корневой узел. Если хотите, можете использовать последовательность, например (<address />, <address2 />)

person dirkk    schedule 31.05.2013
comment
Спасибо! Я знал, что недалеко от решения, но все же последний удар требовался :) - person sailfish; 01.06.2013