Как выполнить итерацию поля XML в SQL Server с помощью функции value()

У меня есть следующее поле XML():

<A>
  <B name = "B1">
    <C>
      <D name = "D1">
        <E name = "E1"/>
        <E name = "E2"/>
        <E name = "E3"/>
      </D>
      <D name = "D2">
        <E name = "E4"/>
        <E name = "E5"/>
        <E name = "E6"/>
      </D>
    </C>
  </B>
  <B name = "B3">
    <C>
      <D name = "D11">
        <E name = "E11"/>
        <E name = "E22"/>
        <E name = "E33"/>
      </D>
      <D name = "D22">
        <E name = "E44"/>
        <E name = "E55"/>
        <E name = "E66"/>
      </D>
    </C>
  </B>
</A>

Если я хочу использовать nodes() и value() для получения данных из XML, что мне делать, результат должен быть таким:

Б Д Е Б1 Д1 Е1 Б1 Д1 Е2 Б1 Д1 Е3 Би 2 Д2 Е4 .. Б3 Д22 Е66

Я пробовал следующий запрос:

SELECT NodePath.value('@name', 'varchar(100)') B,
    NodePath.value('(./C/D/@name)[1]', 'varchar(64)') D,
    NodePath.value('(./C/D/E/@name)[1]', 'varchar(100)') E
FROM XmlTable xt
cross apply xt.XmlField.nodes('/A/B') Node(NodePath)

но мне кажется, что требуется только одно E из разных B

Пример XML недействителен. Закрывающие теги должны использовать символ /, а не символ «\». например: <D>...</D>.

AlwaysLearning 22.12.2020 08:44

@AlwaysLearning, простите, я исправил это.

zening.chen 22.12.2020 08:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
SELECT NodePath.value('@name', 'varchar(100)') B,
    --NodePath.value('(./C/D/@name)[1]', 'varchar(64)') D,
    --NodePath.value('(./C/D/E/@name)[1]', 'varchar(100)') E,
    d.d.value('@name', 'varchar(64)') AS D,
    e.e.value('@name', 'varchar(100)') AS E
FROM XmlTable xt
CROSS APPLY xt.XmlField.nodes('/A/B') AS Node(NodePath)
CROSS APPLY Node.NodePath.nodes('C/D') AS d(d)
CROSS APPLY d.d.nodes('E') AS e(e)

Спасибо, это работает! И я также задаюсь вопросом о его производительности. Будет ли его производительность лучше, чем следующий запрос? SELECT NodePath.value(../../../'@name', 'varchar(100)') B, NodePath.value('@../name', 'varchar(64)') AS D, NodePath.value('@name', 'varchar(100)') AS E FROM XmlTable xt CROSS APPLY xt.XmlField.nodes('/A/B/C/D/E') AS Node(NodePath)

zening.chen 23.12.2020 02:42

[email protected]. В общем, навигация вверх по структуре/иерархии xml (от дочернего к родительскому узлу) с использованием parent:: или аббревиатуры '../' является более дорогостоящей/затратной, чем получение сначала родителя, а затем детей. Вы можете сравнить и проверить различия двух планов выполнения (для подъема по иерархии требуется 2 дополнительных фильтра xpath). Это не означает, что ваше предложение будет медленнее. Более дорогой запрос получает больше памяти, и иногда это может привести к тому, что дорогой запрос будет выполняться быстрее, чем более дешевый. Просто протестируйте его в своей среде и выберите тот, который вам подходит.

lptr 24.12.2020 09:09

Другие вопросы по теме