Как уничтожить .docx XML?

8

Я пытаюсь импортировать XML (на самом деле файл DOCX) в базу данных SQL Server 2008. Я почти новичок в программировании XML. Я много гуглил, но почти все примеры с простым XML-файлом. Здесь XML-файл немного сложен (см. Ниже). Можете ли вы дать мне некоторое представление о том, как я должен создать таблицу для этого XML и какой запрос я должен выполнить на сервере SQL. Мне нужны значения для всех тегов, например, w: rsidP, w: rsidRDefault, w: rsidR для w: p, w: pStyle, w: bookmarkStart, теги w: t и т. Д.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
<w:body>
<w:p w:rsidR="00EF42E0" w:rsidRDefault="00EF42E0" w:rsidP="00EF42E0">
<w:pPr><w:pStyle w:val="Heading1"/>
</w:pPr><w:bookmarkStart w:id="0" w:name="_Toc212523610"/>
<w:r>
<w:t>Summary</w:t>
</w:r>
<w:bookmarkEnd w:id="0"/>
</w:p>
<w:p w:rsidR="00EF42E0" w:rsidRDefault="00EF42E0" w:rsidP="00EF42E0"><w:pPr><w:pStyle w:val="mainbodytext"/><w:ind w:right="-694"/><w:rPr><w:b/><w:bCs/></w:rPr></w:pPr><w:r><w:rPr><w:b/><w:bCs/></w:rPr><w:t>What is the Group Defined Practice for Integrity Management?</w:t></w:r></w:p>
<w:p w:rsidR="00EF42E0" w:rsidRDefault="00EF42E0" w:rsidP="00EF42E0"><w:pPr><w:pStyle w:val="mainbodytext"/></w:pPr><w:r><w:t xml:space="preserve">This Practice is derived from the GP Group Standard, GRP 01 January 2006, </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>Integrity</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t xml:space="preserve"> Management.  In developing QMS it has been possible to embed much of the content of the IM Standard directly into the Group Essentials statements.  For elements 2, 7, 8 and 9 of the Standard it was possible to do that in their entirety and therefore content of those elements are not repeated within this Practice.</w:t></w:r></w:p></w:body></w:document>
user23683
источник

Ответы:

10

При работе с XML в SQL Server вы используете XML Методы типа данных и при измельчением XML документов вы typicly использовать nodes()и value()методы. XML, который у вас есть, также включает в себя несколько пространств имен, поэтому вам нужно указать те, которые вам нужны, с помощью WITH XMLNAMESPACES (Transact-SQL) .

XML довольно сложный, поэтому, не зная, как вы хотите извлекать данные, я могу дать вам только несколько примеров запросов, которые вы затем сможете изменить в соответствии с вашими потребностями.

У вас есть четыре w:pузла, и вот запрос, который выбирает атрибуты из этих узлов. Использование @указывает, что это значение атрибута, который вы хотите-

with xmlnamespaces('http://schemas.openxmlformats.org/wordprocessingml/2006/main' as w)
select P.X.value('@w:rsidR', 'char(8)') as rsidR,
       P.X.value('@w:rsidRDefault', 'char(8)') as rsidRDefault,
       P.X.value('@w:rsidP', 'char(8)') as rsidP
from @doc.nodes('/w:document/w:body/w:p') as P(X);

SQL Fiddle

Если вам, в дополнение к этому, нужен текст в w:tузле, вам нужно добавить cross applyко второму nodes()предложению, которое уничтожит XML внутри w:pузла.

with xmlnamespaces('http://schemas.openxmlformats.org/wordprocessingml/2006/main' as w)
select P.X.value('@w:rsidR', 'char(8)') as rsidR,
       P.X.value('@w:rsidRDefault', 'char(8)') as rsidRDefault,
       P.X.value('@w:rsidP', 'char(8)') as rsidP,
       T.X.value('text()[1]', 'nvarchar(max)') as Text
from @doc.nodes('/w:document/w:body/w:p') as P(X)
  cross apply P.X.nodes('w:r/w:t') as T(X);

SQL Fiddle

В своем вопросе вы сказали, что хотите получить значения из всех тегов. Я не знаю, насколько это полезно для вас, но вы можете создать список «имя-значение» со всеми атрибутами и элементами в XML.

Это даст вам все элементы.

select T.X.value('local-name(.)', 'nvarchar(max)') Name,
       T.X.value('.', 'nvarchar(max)') Value
from @doc.nodes('//*') as T(X)

Перейдите '//*'на '//@*'и вы получите все атрибуты.

select T.X.value('local-name(.)', 'nvarchar(max)') Name,
       T.X.value('.', 'nvarchar(max)') Value
from @doc.nodes('//@*') as T(X)

И вы можете объединить их в одном запросе.

select T.X.value('local-name(.)', 'nvarchar(max)') Name,
       T.X.value('.', 'nvarchar(max)') Value
from @doc.nodes('//@*, //*') as T(X)

SQL Fiddle

Микаэль Эрикссон
источник