XQuery Update Facility versus XSLT?
Last month we discussed Transforming XML using XQuery updates. With XQuery 1.0 update and transform operations are rather challenging to implement. Or you can use some library to get there, like we explained in Updating XML with XQuery 1.0. In any case, we have to admit, compared to XSLT this is a shortcoming.With the XQuery Update Facility, things will change drastically. Let's have a closer look at a concrete usage scenario from a recent question on SSDN.
If preceding-sibling type="zMADDRESS", type="zZip" valueThe proposed XSLT solution is as follows,
should be left unchanged. Else if, preceding-sibling
type="zADDRESS", type="zZip" items should be removed.
And the comma and space which always seem to precede
the zZip in ZAddress or zNeighb must also be removed--
if that is all within a zADDRESS.
For examples:
1. Before:
<tps:c type="zStreet">20 West Row</tps:c>
<tps:c type="zAddress">,</tps:c>
<tps:c type="zNeighb">Canberra City,</tps:c>
<tps:c type="zZip">2600</tps:c>
1. After:
<tps:c type="zStreet">20 West Row</tps:c>
<tps:c type="zAddress">,</tps:c>
<tps:c type="zNeighb">Canberra City</tps:c>
2. Before:
<tps:c type="zStreet">82 Northbourne Ave.</tps:c>
<tps:c type="zAddress">,</tps:c>
<tps:c type="zNeighb">Braddon</tps:c>
<tps:c type="zAddress">,</tps:c>
<tps:c type="zZip">2601</tps:c>
2. After:
<tps:c type="zStreet">82 Northbourne Ave.</tps:c>
<tps:c type="zAddress">,</tps:c>
<tps:c type="zNeighb">Braddon</tps:c>
3. Beofre:
<tps:c type="zMaddress">Box 544, Burra Creek,</tps:c>
<tps:c type="zCity">Queanbeyan,</tps:c>
<tps:c type="zZip">2620</tps:c>
3. After, no change because one its preceding-siblings is "zMaddress".
<?xml version='1.0'?>What would this look like using XQuery Update Facility?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tps="http://www.typefi.com/ContentXML">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:for-each select="@*">
<xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="*|text()"/>
</xsl:element>
</xsl:template>
<xsl:template match="tps:c[@type='zZip']">
<xsl:choose>
<xsl:when test="preceding-sibling::tps:c[@type='zAddress']">
<!-- removed -->
</xsl:when>
<xsl:otherwise><xsl:copy-of select="."/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="tps:c[@type='zAddress']">
<xsl:choose>
<xsl:when test="text() = ',' and following-sibling::tps:c[1][@type='zZip']">
<!-- removed -->
</xsl:when>
<xsl:otherwise><xsl:copy-of select="."/></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
declare namespace tps = "http://www.typefi.com/ContentXML";I don't want to end up in one of those endless XQuery versus XSLT discussions. But beside the fact that XQuery Update Facility adds a nice palette of new functionality to XQuery, I believe it offers concise, well readable solutions.
copy $doc := .
modify
(delete node $doc//tps:c[@type='zZip']
[preceding-sibling::tps:c[@type='zAddress']],
delete node $doc//tps:c[@type='zAddress']
[.=(","," ")]
[following-sibling::tps:c[1][@type='zZip']])
return $doc
Labels: XQuery

0 Comments:
Post a Comment
<< Home