Исключить один тип элемента из XML с помощью XQUERY - PullRequest
3 голосов
/ 30 сентября 2011

Вот моя проблема ... Мне нужно выбрать все во всем XML-документе, но пропустить один тег.К сожалению, этот тег может иметь разную глубину.

Используя следующий пример кода, я хотел бы удалить все элементы <crud>, <crud2> и <...> (и т. Д.).<crud> может иметь больше детей, но я все равно их не хочу.

<body>
  <h2/>
  <crud>
    <crud2/>
    <...>
  </crud>
  <div>
    <p> </p>
  </div>
  <div>
    <p>
    </p>
    <crud>
      <crud2/>
      <...>
    </crud>
  </div>
</body>

Я пробовал несколько методов.

let $body := "the xml sample"
return $body/*[fn:not(descendant-or-self::crud)]

Этот метод требует много.Он удаляет весь блок <div>, который содержит crud, но мне нужны <div> и <p>, которые включены.Кажется, что все другие методы удаляют только прямые <crud> дочерние элементы <body>, либо он также удаляет контейнер.

Итак, мне по существу нужен метод, который достигает каждого элемента и удаляет все <crud>без всякого другого.

Окончательный XML должен выглядеть следующим образом:

<body>
  <h2/>
  <div>
    <p> </p>
  </div>
  <div>
    <p>
    </p>
  </div>
</body>

Я очень ценю любую помощь.

Ответы [ 2 ]

3 голосов
/ 30 сентября 2011

Этот вид обработки легче всего выполнить с помощью XSLT, который более выразителен, чем XQuery :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>


 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="crud"/>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному документу XML :

<body>
    <h2/>
    <crud>
        <crud2/>
    </crud>
    <div>
        <p> </p>
    </div>
    <div>
        <p>     </p>
        <crud>
            <crud2/>
        </crud>
    </div>
</body>

желаемый, правильный результат получен :

<body>
    <h2/>

    <div>
        <p> </p>
    </div>
    <div>
        <p>     </p>

    </div>
</body>

Пояснение :

  1. Правило идентификации копирует каждый узел "как есть".

  2. Один шаблон переопределяет правило / шаблон идентификации. Он соответствует элементу anu crud и его пустому телу.в результате crud (и любое поддерево, возглавляемое им) будет удалено с выхода.

0 голосов
/ 03 октября 2011

Это простая работа, используя Обновление XQuery и оператор копирования :

copy $c := .
modify delete node $c//crud
return $c

Если вы можете изменить исходный файл, вы можете даже использоватькороче delete node //crud.

...