Изменение имени узла через Xquery

Я пытаюсь создать xquery, который изменит имя узла с «CNode3» на «ChangedNode3» всякий раз, когда дочерним элементом («CCNode1») «CNode3» является «CCValue1».

<PNode>
  <CNode1>Node1</CNode1>
  <CNode2>Node2</CNode2>
  <CNode3>
     <CCNode1>CCValue1</CCNode1>
     <CCNode2>CCValue2</CCNode2>
  </CNode3>
  <CNode3>
     <CCNode1>CCValue3</CCNode1>
     <CCNode2>CCValue4</CCNode2>
  </CNode3></PNode>

Не получил много помощи в Интернете для этого конкретного сценария. Я проверил ссылку ниже, но она меняет имя всех «CNode3» на «ChangedNode3». PFB ссылка: http://www.xqueryfunctions.com/xq/functx_change-element-names-deep.html


person user3839347    schedule 26.12.2017    source источник


Ответы (1)


Функция functx:change-element-names-deep() оценивает только имена элементов. Вам нужно немного больше настройки.

Вы можете использовать переключатель типов в локальной функции:

declare function local:transform($nodes as node()*) as item()* {
    for $node in $nodes
    return 
        typeswitch($node)
            case text() return $node
            case comment() return $node
            case attribute() return $node
            case processing-instruction() return $node
            case element(CNode3) 
              return 
                if ($node[CCNode1 eq "CCValue1"]) then 
                  element ChangedNode3 {( $node/@*, local:transform($node/node()) )} 
                else 
                  element {name($node)} {($node/@*, local:transform($node/node()))}
            case element() 
              return element {name($node)} {($node/@*, local:transform($node/node()))}
            default return local:transform($node/node())
};

Полное описание шаблона преобразования typeswitch.

person Mads Hansen    schedule 26.12.2017