简体   繁体   English

XQUERY更新XML参数

[英]XQUERY to update XML parameters

Given the following XML snippet, for each distinct ElementID I need to check, that if the CurrentValue in one of the elements is different then update all the CurrentValues with the value which is changed. 给定以下XML代码段,对于每个不同的ElementID,我都需要检查一下,如果元素之一中的CurrentValue不同,则使用更改后的值更新所有CurrentValues。

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

The result should be 结果应该是

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

This seems more suited to XSLT. 这似乎更适合XSLT。 If you can use XSLT, here's one option... 如果可以使用XSLT,这是一个选择...

XML Input (modified to be well-formed) 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 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 Output 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>

Assuming (1) that the new value to be used is the last one which appears on the elements of a given ID (so this answer is comparable to Daniel Haley's), (2) that the input and output are to be as conjectured by Daniel Haley, and (3) that your input document is at http://example.com/imdoc.xml , then something like the following XQuery module should do the trick. 假设(1)要使用的新值是出现在给定ID元素上的最后一个值(因此此答案与Daniel Haley的答案相当),(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>

If assumption (2) doesn't apply, a slightly different formulation is: 如果假设(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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM