2016-10-21 2 views
2

Я пытаюсь найти способ синтаксического анализа довольно большого XML-файла в таблицу, которая просто показывает имя узла и его значение. В XML нет никаких атрибутов, но есть несколько вложенных узлов.Анализ XML в таблице в SQL (только узлы с значениями)

Поскольку там XML генерируется динамически, нет возможности узнать точную глубину этого гнездования. Но можно с уверенностью предположить, что только LAST CHILD NODE любой ветки будет содержать данные.

Это моя попытка решения, но проблема в том, что при доступе к родительскому узлу данные из каждого дочернего объекта объединяются в качестве значения.

DECLARE @ProjectXML XML 
SET @ProjectXML = ' 
<Project> 

    <ProjectId>1</ProjectId> 
    <OrganizationId>1</OrganizationId> 
    <Title>This is a Test Title</Title> 
    <Description>This is a Test Description</Description> 
    <ProjectType> 
    <Id>1</Id> 
    <Name>Test Name</Name> 
    <Outer> 
     <Inner1>Hi</Inner1> 
     <Inner2>There</Inner2> 
    </Outer> 
    </ProjectType> 
</Project> 
' 
SELECT 
n.value('local-name(.)','VARCHAR(100)') AS Name, 
n.value('.','VARCHAR(MAX)') AS Value 

FROM @ProjectXML.nodes('//*') AS ProjectXML(n) 

Какие результаты в:

Project   11This is a Test TitleThis is a Test Description1Test NameHiThere 
ProjectId   1 
OrganizationId 1 
Title    This is a Test Title 
Description  This is a Test Description 
ProjectType  1Test NameHiThere 
Id    1 
Name    Test Name 
Outer    HiThere 
Inner1   Hi 
Inner2   There 

Есть ли способ (с помощью XQuery возможно?) Игнорировать родительские узлы, которые не содержат никаких данных, и возвращать только значения для дочерних узлов, которые делают?

** Бонусные баллы, если можно вернуть имя каждого результата в виде форматированного списка из его родительских узлов, таких как:

Project - ProjectId       1 
Project - OrganizationId     1 
Project - Title        This is a Test Title 
Project - Description      This is a Test Description 
Project - Project Type - Id     1 
Project - Project Type - Name    Test Name 
Project - Project Type - Outer - Inner1  Hi 
Project - Project Type - Outer - Inner2  There 

ответ

1

Заглянуть в http://beyondrelational.com/modules/2/blogs/28/posts/10495/xquery-lab-58-select-from-xml.aspx

Select * from XMLTable(@ProjectXML) where value is not null 

Возвращает больше, чем вы можете пожелать, но вы можете адаптировать к вашим потребностям

enter image description here

+0

Вы только что спасли меня как минимум на 3 дня, вытаскивая мои волосы. Это отлично работало, колонки «FullPath» и «Value» были именно тем, что мне нужно. Я провел это против моих больших XML-файлов, и все прошло гладко. Я не могу вас поблагодарить! –

+0

@ JustinTrenary Я был доволен, когда я наткнулся на него. Мне стыдно признаться, как выглядела моя попытка. Я сделал некоторые драматические трюки в моем случае, но не хотел брать кредит за его работу. Кстати, я дал вам Plus1, потому что это был хороший и хорошо сформированный вопрос. Я был бы в восторге, если бы все новые члены были на половину своей работы. –

+0

Мне было бы любопытно, что ваши попытки * ашаминга выглядели так :-) Я просто отправил ответ с довольно простой 'XQuery' ... В любом случае +1 за вашу честность :-) – Shnugo

1

Это можно было бы сделать гораздо проще ...

Это немного сложнее, чтобы получить /text() узла, если нет /text(). Но есть empty() -функции и not() -функции:

SELECT 
n.value('local-name(.)','VARCHAR(100)') AS Name, 
n.value('.','VARCHAR(MAX)') AS Value 
FROM @ProjectXML.nodes('//*[not(empty(text()))]') AS ProjectXML(n) 

И вы могли бы read this

Старая FROM OPENXML с WHERE text IS NOT NULL будет поставлять те же плюс более подробную информацию о положении внутри XML.

Но связанная функция Джона Капельлетти великолепна. Просто придерживайтесь этого ...

 Смежные вопросы

  • Нет связанных вопросов^_^