[xquery-talk] Selecting everything before and after path, but without duplicated leafs

Michael Kay mike at saxonica.com
Mon Feb 11 09:07:26 PST 2008


> > what output would you like to see?
> 
> I would like to preserve the original XML file, but only add 
> an extra tag, so I would like to have this output:
> 
> <ead>
>  <banana/>
>  <archdesc>
>    <dsc>
>      <c00/>
>      <SELECT>
>      <c01/>
>      </SELECT>
>      <c02/>
>    </dsc>
>  </archdesc>
>  <custard/>
> </ead>

In XSLT this is simply an identity template that copies all elements
unchanged:

<xsl:template match="*">
  <xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>

(or a variation of that if you need to handle attributes)

supplemented by a template for the element you want to change:

<xsl:template match="c01">
  <SELECT><xsl:next-match/></SELECT>
</xsl:template>

(You can write a more elaborate match pattern if you need to be more
selective.)

In XQuery you need to program the recursive descent by hand:

declare function local:processNode($e as node()) as element() {
  typeswitch ($e) {
    case element(c01) return <SELECT>{$e}</SELECT>
    case element() return 
      element {node-name($e)} {for $c in $e/child::node() return
local:processNode($c)}
    default return $e
  }
}

local:processNode(doc('abc.xml')/*)

plus a bit of extra logic if you need to handle attributes or namespaces.

Michael Kay
http://www.saxonica.com/
  



More information about the talk mailing list