2011-05-01 60 views
2

这里是我的xmlXQuery更新问题

<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> 

我需要0.50美分,至更新所有书籍的价格。我怎样才能做到这一点?

+0

你必须使用XQuery来做这件事,还是可以使用XSLT? – 2011-05-01 16:55:00

+0

好问题,+1。请参阅我的回答以获取建议和完整的,非常短的XSLT解决方案:) – 2011-05-01 16:58:40

+0

我必须使用xQuery。 – zach 2011-05-01 23:31:32

回答

1

XSLT是显著更合适的不是XQuery来使用这类任务的:

这种转变

<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> 

时所提供的XML文档应用:

<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> 

产生想要的,正确的结果

<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> 
+0

我必须使用xQuery并更改现有的xml。 xslt非常漂亮,我希望我可以使用它:( – zach 2011-05-01 23:31:06

+0

@zach:在XQuery中有类似'typeswitch'(从来没有不幸使用它) - 读了它并使用它。它是一个非常原始的匹配机制,并可能有所帮助。http://www.w3.org/TR/xquery/#id-typeswitch – 2011-05-02 00:23:54

3

如果您正在寻找使用XQuery更新设施的解决方案:

for $p in //price return 
replace value of node $p with $p + 0.50 
+0

这将改变我现有的XML? – zach 2011-05-01 23:31:54

2

在XQuery中,递归函数是用来干什么的转变。

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 
}; 

那么如果书籍文档为$引用的书籍:

local:reprice($books) 

进一步的讨论和例子在http://en.wikibooks.org/wiki/XQuery/Typeswitch_Transformations

另外,使用XML数据库如存在,但DB和更新原位:

for $price in $books//price 
let $newprice := xs:decimal($price) + 0.5 
return update replace $price with elememt price {$newprice} 

注意,XQuery更新扩展主要是依赖于实现,直到XQuery更新更广泛的支持