Как суммировать различные узлы элемента в xml, чтобы присвоить значение в другом узле - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть xml на sql сервере, который выглядит как:

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

1 Ответ

1 голос
/ 20 апреля 2020

Я думаю, что будет простой способ сделать это, но вот один из вариантов:

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)

Я не люблю выбирать узлы, используя значение тега description. Было бы лучше, если бы у вас был другой путь.

Кроме того, было бы лучше, если бы эти данные были нормализованы в таблицах SQL и построили это XML с помощью предложения 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...