¿Cómo triturar .docx XML?

8

Estoy tratando de importar un xml (en realidad un archivo docx) a una base de datos del servidor sql 2008. Soy casi un novato en programación XML. Busqué en Google mucho, pero casi todos los ejemplos que hay con un simple archivo xml. Aquí el archivo xml es poco complejo (ver más abajo). ¿Puede darme alguna idea de cómo debo crear la tabla para este XML y qué consulta debo ejecutar en el servidor SQL? Necesito valores para todas las etiquetas, por ejemplo, w: rsidP, w: rsidRDefault, w: rsidR de w: p, w: pStyle, w: bookmarkStart, w: t tags, etc.

<?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
fuente

Respuestas:

10

Cuando trabajas con XML en SQL Server, usas los métodos de tipo de datos xml y cuando trizas documentos XML usualmente usas los métodos nodes()y value(). El XML que tiene aquí también incluye una serie de espacios de nombres, por lo que debe especificar los que necesita usando WITH XMLNAMESPACES (Transact-SQL) .

El XML es bastante complejo, por lo que sin saber cómo desea que se extraigan los datos, solo puedo darle un par de consultas de muestra que luego puede modificar a lo que sea que necesite.

Tiene cuatro w:pnodos y aquí hay una consulta que obtiene los atributos de esos nodos. El uso @especifica que es el valor de un atributo que desea:

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);

Violín de SQL

Si además de eso desea el texto en el w:tnodo, debe hacer una cláusula cross applya una segunda nodes()que triturará el XML dentro del w:pnodo.

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);

Violín de SQL

Usted dijo en su pregunta que desea obtener los valores de todas las etiquetas. No sé qué tan útil es esto para usted, pero puede crear una lista de Nombre-Valor con todos los atributos y elementos en el XML.

Esto te dará todos los elementos.

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

Cambie '//*'a '//@*'y obtendrá todos los atributos.

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

Y también puede combinarlos en una consulta.

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

Violín de SQL

Mikael Eriksson
fuente