查找匹配的节点,如果存在则更新,否则附加到根XML

时间:2014-11-12 09:48:24

标签: sql-server xquery

我正在尝试找到迭代父xml的最有效方法,尝试从传递的子xml中找到匹配项。如果找到完全匹配,我需要更新父xml中匹配的xml节点,或者将新的子xml附加到父xml中。

    --There are 2 AttributeBalance Nodes, each having 3 Attribute Nodes.
    DECLARE @ParentFromTableXML XML

    SET @ParentFromTableXML = '
    <AttributeGroup>
    <GroupID>2009</GroupID>
    <GroupCode>Clothing</GroupCode>
    <GroupDescription>Clothing</GroupDescription>
    <AttributeBalanceGroup>
        <CreditTotal>935</CreditTotal>
        <AttributeBalance>
            <Credit>93</Credit>
            <Attribute>
                <TypeID>1013</TypeID>
                <TypeName>Size</TypeName>
                <ValueID>1015</ValueID>
                <Value>S</Value>
            </Attribute>
            <Attribute>
                <TypeID>1018</TypeID>
                <TypeName>Color</TypeName>
                <ValueID>1029</ValueID>
                <Value>Black</Value>
            </Attribute>
        </AttributeBalance>
        <AttributeBalance>
            <Credit>78</Credit>
            <Attribute>
                <TypeID>1013</TypeID>
                <TypeName>Size</TypeName>
                <ValueID>1015</ValueID>
                <Value>S</Value>
            </Attribute>
            <Attribute>
                <TypeID>1018</TypeID>
                <TypeName>Color</TypeName>
                <ValueID>1030</ValueID>
                <Value>Red</Value>
            </Attribute>
        </AttributeBalance>
    </AttributeBalanceGroup>
</AttributeGroup>'

    /* This has 2 AttributeBalance Nodes, each having 3 Attribute Nodes. 1 Attribute Node exists in the @ParentFromTableXML while one does not. The one which does not, i need to append to the @ParentFromTableXML */

    DECLARE @ChildParamXML XML

        SET @ChildParamXML = '
        <AttributeGroup>
    <GroupID>2009</GroupID>
    <GroupCode>Clothing</GroupCode>
    <GroupDescription>Clothing</GroupDescription>
    <AttributeBalanceGroup>
        <CreditTotal>935</CreditTotal>
        <AttributeBalance>
            <Credit>12</Credit>
            <Attribute>
                <TypeID>1013</TypeID>
                <TypeName>Size</TypeName>
                <ValueID>1015</ValueID>
                <Value>S</Value>
            </Attribute>
            <Attribute>
                <TypeID>1018</TypeID>
                <TypeName>Color</TypeName>
                <ValueID>1029</ValueID>
                <Value>Black</Value>
            </Attribute>
        </AttributeBalance>
        <AttributeBalance>
            <Credit>65</Credit>
            <Attribute>
                <TypeID>1013</TypeID>
                <TypeName>Size</TypeName>
                <ValueID>1017</ValueID>
                <Value>XXXL</Value>
            </Attribute>
            <Attribute>
                <TypeID>1018</TypeID>
                <TypeName>Color</TypeName>
                <ValueID>1029</ValueID>
                <Value>Black</Value>
            </Attribute>
        </AttributeBalance>
    </AttributeBalanceGroup>
</AttributeGroup>'

我想过尝试使用FLWOR语句,就像这样

SELECT @ParentFromTableXML.query('
    for $Attrib in /AttributeGroup/AttributeBalanceGroup/AttributeBalance/Attribute         
    return
        for $PassedAttrib in //@ChildParamXML
        return
          if (data($Attrib/TypeID) = data($PassedAttrib)) then
            --Need to return the current node, so i can add the ChildParamXML "Credit" 
            <Result>equal</Result>       
          else
            <Result>Not-equal</Result>           

               ') AS Result

我还想过使用节点比较运算符“is”,类似这样的

SELECT @ParentFromTableXML.query('       
    if ( (//AttributeGroup/AttributeBalanceGroup/AttributeBalance/Attribute)[1]       
          is        
          (//@ChildParamXML)[1] )        
    then       
          --Need to return the current node, so i can add the ChildParamXML "Credit" to the ParentFromTableXML "Credit"
          <Result>equal</Result>       
    else       
          <Result>Not-equal</Result>       
         ') as Result   

一旦找到匹配项,我希望返回XML节点并使用.modify()命令通过添加@ChildParamXML“Credit”金额来更新@ParentFromTableXML“Credit”金额。这必须仅发生在每个节点的完全匹配节点上。

DECLARE @sumCredit DECIMAL

SET @sumCredit = (/*Found Parent XML Node*/ + /*Found Child XML Node*/)
@ParentFromTableXML.modify('replace value of (/ResultXML/Credit/text())[1]

  (sql:variable("@sumCredit")')

如果在整个@ParentFromTableXML中找不到匹配项,我需要将@ChildParamXML附加到现有的@ParentFromTableXML。

所以我的最终结果应该是

-- This XML would be the end result, with 11 AttributeBalance Items since one was appended and 3 which were updated

    DECLARE @EndResultXML XML

    SET @EndResultXML = '
    <AttributeGroup>
    <GroupID>2009</GroupID>
    <GroupCode>Clothing</GroupCode>
    <GroupDescription>Clothing</GroupDescription>
    <AttributeBalanceGroup>
        <CreditTotal>248</CreditTotal>
        <AttributeBalance>
            <Credit>105</Credit>
            <Attribute>
                <TypeID>1013</TypeID>
                <TypeName>Size</TypeName>
                <ValueID>1015</ValueID>
                <Value>S</Value>
            </Attribute>
            <Attribute>
                <TypeID>1018</TypeID>
                <TypeName>Color</TypeName>
                <ValueID>1029</ValueID>
                <Value>Black</Value>
            </Attribute>
        </AttributeBalance>
        <AttributeBalance>
            <Credit>78</Credit>
            <Attribute>
                <TypeID>1013</TypeID>
                <TypeName>Size</TypeName>
                <ValueID>1015</ValueID>
                <Value>S</Value>
            </Attribute>
            <Attribute>
                <TypeID>1018</TypeID>
                <TypeName>Color</TypeName>
                <ValueID>1030</ValueID>
                <Value>Red</Value>
            </Attribute>
        </AttributeBalance>
        <AttributeBalance>
            <Credit>65</Credit>
            <Attribute>
                <TypeID>1013</TypeID>
                <TypeName>Size</TypeName>
                <ValueID>1020</ValueID>
                <Value>XXXL</Value>
            </Attribute>
            <Attribute>
                <TypeID>1018</TypeID>
                <TypeName>Color</TypeName>
                <ValueID>1029</ValueID>
                <Value>Black</Value>
            </Attribute>
        </AttributeBalance>
    </AttributeBalanceGroup>
</AttributeGroup>
'

非常感谢任何帮助。

0 个答案:

没有答案