2013-02-20 50 views
0

给定以下XML片段,对于每个需要检查的不同ElementID,如果其中一个元素中的CurrentValue不同,则使用更改后的值更新所有CurrentValues。XQUERY更新XML参数

<im:Element> 
    <im:ElementID>1</im:ElementID> 
    <im:CurrentValue>OldValue1</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>1</im:ElementID> 
    <im:CurrentValue>OldValue1</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>1</im:ElementID> 
    <im:CurrentValue>NewValue1</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>2</im:ElementID> 
    <im:CurrentValue>OldValue2</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>2</im:ElementID> 
    <im:CurrentValue>NewValue2</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>2</im:ElementID> 
    <im:CurrentValue>OldValue2</im:CurrentValue> 
</im:Element> 
----- 

结果应该是

<im:Element> 
    <im:ElementID>1</im:ElementID> 
    <im:CurrentValue>NewValue1</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>1</im:ElementID> 
    <im:CurrentValue>NewValue1</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>1</im:ElementID> 
    <im:CurrentValue>NewValue1</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>2</im:ElementID> 
    <im:CurrentValue>NewValue2</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>2</im:ElementID> 
    <im:CurrentValue>NewValue2</im:CurrentValue> 
</im:Element> 
<im:Element> 
    <im:ElementID>2</im:ElementID> 
    <im:CurrentValue>NewValue2</im:CurrentValue> 
</im:Element> 
----- 
+0

这似乎更适合XSLT。你可以使用XSLT吗? – 2013-02-20 06:32:24

+1

如果您有几个具有相同元素ID和不同值的im元素元素,您如何知道哪个元素发生了更改并因此包含新值?应该将序列中的最后一个值传播到该元素类型的所有事件中?或者,新值都以字符串“NewValue”开始的关键是......? – 2013-02-21 00:47:54

+0

查找元素的newValue的方法是检查与该特定元素ID的所有出现中的值不同的唯一值。 – cornerstone 2013-02-21 08:47:28

回答

0

这似乎更适合XSLT。如果你可以使用XSLT,这里有一个选项...

XML输入(修改得到很好的形成)

<im:Doc xmlns:im="im"> 
    <im:Element> 
     <im:ElementID>1</im:ElementID> 
     <im:CurrentValue>OldValue1</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>1</im:ElementID> 
     <im:CurrentValue>OldValue1</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>1</im:ElementID> 
     <im:CurrentValue>NewValue1</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>2</im:ElementID> 
     <im:CurrentValue>OldValue2</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>2</im:ElementID> 
     <im:CurrentValue>OldValue2</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>2</im:ElementID> 
     <im:CurrentValue>NewValue2</im:CurrentValue> 
    </im:Element> 
</im:Doc> 

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:im="im"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="im:CurrentValue"> 
     <xsl:copy> 
      <xsl:value-of select="(//im:Element[im:ElementID=current()/../im:ElementID]/im:CurrentValue)[last()]"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

XML输出

<im:Doc xmlns:im="im"> 
    <im:Element> 
     <im:ElementID>1</im:ElementID> 
     <im:CurrentValue>NewValue1</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>1</im:ElementID> 
     <im:CurrentValue>NewValue1</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>1</im:ElementID> 
     <im:CurrentValue>NewValue1</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>2</im:ElementID> 
     <im:CurrentValue>NewValue2</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>2</im:ElementID> 
     <im:CurrentValue>NewValue2</im:CurrentValue> 
    </im:Element> 
    <im:Element> 
     <im:ElementID>2</im:ElementID> 
     <im:CurrentValue>NewValue2</im:CurrentValue> 
    </im:Element> 
</im:Doc> 
+0

NewValue *不一定必须是最后一个元素。 – cornerstone 2013-02-21 08:26:49

0

假设(1)要使用的新值是出现在给定ID的元素上的最后一个值(因此该答案可与Daniel Haley's相媲美),(2)输入和输出将如同猜测Daniel Haley和(3)你的输入文档在http://example.com/imdoc.xml,那么类似下面的XQuery模块应该可以做到这一点。

declare namespace im = "im"; 

<im:Doc>{ 
    let $doc := doc('http://example.com/imdoc.xml') 
    for $e in $doc/im:Doc/im:Element 
    let $eid := $e/im:ElementID, 
     $lastval := ($e/../im:Element[im:ElementID = $eid]) 
        [last()] 
        /im:CurrentValue 
    return <im:Element>{ $eid, $lastval}</im:Element> 
}</im:Doc> 

如果假定(2)不适用,稍有不同的配方:

let $input := doc('http://example.coms/imdoc.xml') 
        /im:Doc/im:Element 
for $e in $input 
let $eid := $e/im:ElementID, 
    $lastval := ($input[im:ElementID = $eid]) 
       [last()]/im:CurrentValue 
return <im:Element>{ $eid, $lastval}</im:Element> 
+0

NewValue *不一定是最后一个元素。 – cornerstone 2013-02-21 08:28:28

+0

那么你怎么决定哪个元素是“最新”? – 2013-02-21 08:33:55

+0

找出元素的最新值的方法是检查与该特定元素ID的所有出现中的值不同的唯一值。 – cornerstone 2013-02-21 08:48:07