可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Here is my xml
<book asin="0201100886" created="128135928" lastLookupTime="128135928"> <price>102.00</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0122513363" created="128135600" lastLookupTime="128136224"> <price>50.95</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0201441241" created="128136896" lastLookupTime="128136896"> <price>108.20</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0471250600" created="128136896" lastLookupTime="128136896"> <price>107.95</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0321193628" created="128136896" lastLookupTime="128136896"> <price>112.40</price> </book>
I need to update all the books prices by 0.50 cents. How can I do this?
回答1:
If you are looking for a solution using XQuery Update Facility:
for $p in //price return replace value of node $p with $p + 0.50
回答2:
In XQuery, a recursive function is used to do the transformation.
declare function local:reprice($nodes as node()*) { for $node in $nodes return typeswitch($node) case element(price) return element price {xs:decimal($node) + 0.5} case element( return element {name($node)} { $node/@*, local:reprice($node/node())} default return $node };
then if the books document is referenced as $books:
local:reprice($books)
Further discussion and examples are in http://en.wikibooks.org/wiki/XQuery/Typeswitch_Transformations.
Alternatively, use an XML database such as eXist-db and update insitu:
for $price in $books//price let $newprice := xs:decimal($price) + 0.5 return update replace $price with elememt price {$newprice}
Note that XQuery update extensions are mainly implementation-dependant until XQuery Update is more widely supported
回答3:
XSLT is significantly more appropriate to use than XQuery for such kind of tasks:
This transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="price/text()"> <xsl:value-of select="format-number(. + 0.50, '##0.00')"/> </xsl:template> </xsl:stylesheet>
when applied on the provided XML document:
<books> <book asin="0201100886" created="128135928" lastLookupTime="128135928"> <price>102.00</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0122513363" created="128135600" lastLookupTime="128136224"> <price>50.95</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0201441241" created="128136896" lastLookupTime="128136896"> <price>108.20</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0471250600" created="128136896" lastLookupTime="128136896"> <price>107.95</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0321193628" created="128136896" lastLookupTime="128136896"> <price>112.40</price> </book> </books>
produces the wanted, correct result:
<books> <book asin="0201100886" created="128135928" lastLookupTime="128135928"> <price>102.50</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0122513363" created="128135600" lastLookupTime="128136224"> <price>51.45</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0201441241" created="128136896" lastLookupTime="128136896"> <price>108.70</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0471250600" created="128136896" lastLookupTime="128136896"> <price>108.45</price> <purchaseDate>2005-01-22</purchaseDate> </book> <book asin="0321193628" created="128136896" lastLookupTime="128136896"> <price>112.90</price> </book> </books>