首页 > 解决方案 > 如何对xml中的不同元素节点求和以在另一个节点中赋值

问题描述

我在 sql server 中有一个 xml,如下所示:

<Student version="2">
  <Section name="Report">
    <Glossary>
      <Item name="Some text"</Item>
    </Glossary>
    <InputNumber type="int" min="0" max="100" title="Maths" format="normal" description="Marks obtained in Maths out of 100">
      <Value>70</Value>
    </InputNumber>
    <InputNumber type="int" min="0" max="100" title="Science" format="normal" description="Marks obtained in Science out of 100">
      <Value>60</Value>
    </InputNumber>
    <InputNumber type="int" min="0" max="100" title="English" format="normal" description="Marks obtained in English out of 100">
      <Value>80</Value>
    </InputNumber>
 <InputNumber type="float" min="100" max="100" title="Total " format="normal" description="Total  of all subjects marks added together.">
      <Value/>
    </InputNumber>
    <InputNumber type="int" min="0" max="10000" title="How many students in the class?" format="normal" description="total students>
      <Value>19</Value>
    </InputNumber>
    <InputNumber type="int" min="0" max="100" title="How many subjects are there?" format="normal" description="total subjects">
      <Value>3</Value>
    </InputNumber>
</Section>
<Section>
....
</Section>
</Student>

在这里,/Student[1]/Section[1]/InputNumber[4] 的值是所有科目中所有分数的总和,在这种情况下为 210。

如何获取节点中的值总和:/Student[1]/Section[1]/InputNumber[1], /Student[1]/Section[1]/InputNumber[2], /Student[1]/Section [1]/InputNumber[3] 并将其分配给 /Student[1]/Section[1]/InputNumber[4]。

标签: sql-serverxml

解决方案


我想会有一种简单的方法来做到这一点,但这里有一个变体:

DECLARE @DataXML XML;

SET @DataXML = '<Student version="2">
    <Section name="Report">
        <Glossary>
            <Item name="Some text"></Item>
        </Glossary>
        <InputNumber type="int" min="0" max="100" title="Maths" format="normal" description="Marks out of 100">
            <Value>70</Value>
        </InputNumber>
        <InputNumber type="int" min="0" max="100" title="Science" format="normal" description="Marks out of 100">
            <Value>60</Value>
        </InputNumber>
        <InputNumber type="int" min="0" max="100" title="English" format="normal" description="Marks out of 100">
            <Value>80</Value>
        </InputNumber>
        <InputNumber type="float" min="100" max="100" title="Total " format="normal" description="Total  of all subjects marks added together.">
            <Value />
        </InputNumber>
        <InputNumber type="int" min="0" max="10000" title="How many students in the class?" format="normal" description="total students">
            <Value>19</Value>
        </InputNumber>
        <InputNumber type="int" min="0" max="100" title="How many subjects are there?" format="normal" description="total subjects">
            <Value>3</Value>
        </InputNumber>
    </Section>
</Student>';


SET @DataXML.modify('insert text{sum(./Student[@version="2"]/Section[@name="Report"]/InputNumber[@description="Marks out of 100"]/Value)} into (./Student[@version="2"]/Section[@name="Report"]/InputNumber[@description="Total  of all subjects marks added together."]/Value)[1]');

SELECT @DataXML;

text这个想法是为这个节点插入:

(./Student[@version="2"]/Section[@name="Report"]/InputNumber[@description="Total  of all subjects marks added together."]/Value)[1]

其中一些文字很简单:

sum(./Student[@version="2"]/Section[@name="Report"]/InputNumber[@description="Marks out of 100"]/Value)

我不喜欢使用描述标签值选择节点。如果你有其他方法会更好。

此外,如果您在 SQL 表中对这些数据进行规范化,并在将其发送到应用程序之前构建此XMLusing子句,那就更好了。FOR XML


您可以像这样过滤一些节点:

SET @DataXML.modify('insert text{sum(./Student[@version="2"]/Section[@name="Report"]/InputNumber[@title="Maths" or @title="Science" or @title="English"]/Value)} into (./Student[@version="2"]/Section[@name="Report"]/InputNumber[@description="Total  of all subjects marks added together."]/Value)[1]');

使用标题:

(./Student[@version="2"]/Section[@name="Report"]/InputNumber[@title="Maths" or @title="Science" or @title="English"]/Value)

最好添加一个类型input并通过它过滤 - 例如添加属性type=mark


推荐阅读