Comment déchiqueter le XML de .docx?

8

J'essaie d'importer un xml (en fait un fichier docx) dans une base de données SQL Server 2008. Je suis presque novice en programmation XML. J'ai googlé beaucoup, mais presque tous les exemples existent avec un simple fichier xml. Ici, le fichier xml est peu complexe (voir ci-dessous). Pouvez-vous s'il vous plaît me donner une idée de la façon dont je dois créer la table pour ce XML et quelle requête dois-je exécuter sur le serveur SQL. J'ai besoin de valeurs pour toutes les balises, par exemple w: rsidP, w: rsidRDefault, w: rsidR de w: p, w: pStyle, w: bookmarkStart, w: t balises, 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
la source

Réponses:

10

Lorsque vous travaillez avec XML dans SQL Server, vous utilisez les méthodes de type de données xml et lors de la destruction de documents XML, vous utilisez généralement les méthodes nodes()et value(). Le XML que vous avez ici comprend également un certain nombre d'espaces de noms, vous devez donc spécifier ceux dont vous avez besoin avec WITH XMLNAMESPACES (Transact-SQL) .

Le XML est assez complexe, donc sans savoir comment vous voulez que les données soient extraites, je ne peux que vous donner quelques exemples de requêtes que vous pourrez ensuite modifier en fonction de vos besoins.

Vous avez quatre w:pnœuds et voici une requête qui récupère les attributs de ces nœuds. L'utilisation @indique que c'est la valeur d'un attribut que vous souhaitez-

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

Si vous voulez en plus du texte dans le w:tnœud, vous devez faire cross applyune deuxième nodes()clause qui déchiquetera le XML dans le w:pnœud.

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

Vous avez dit dans votre question que vous souhaitez obtenir les valeurs de toutes les balises. Je ne sais pas à quel point cela vous est utile, mais vous pouvez créer une liste nom-valeur avec tous les attributs et éléments du XML.

Cela vous donnera tous les éléments.

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

Changez '//*'en '//@*'et vous obtiendrez tous les attributs.

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

Et vous pouvez également les combiner en une seule requête.

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

SQL Fiddle

Mikael Eriksson
la source