如果所有元素具有相同的名称,如何从XML检索数据?

时间:2016-09-16 08:59:26

标签: sql sql-server xml tsql linq-to-xml

之前,请看:

SQL-Server XML-Bulk-Import and reading as table-data

这是一个以下问题。

XML:

<BMECAT>
    <T_NEW_CATALOG>
        <ARTICLE mode="new">
            <SUPPLIER_AID>9900026005</SUPPLIER_AID>
            <ARTICLE_DETAILS>
                <DESCRIPTION_SHORT>Totalstop fetra f. LF850x500mm</DESCRIPTION_SHORT>                    
                <EAN>4017976822105</EAN>
                <KEYWORD>FK_UNION</KEYWORD>
                <KEYWORD>starken</KEYWORD>
                <KEYWORD>Transport</KEYWORD>
                <KEYWORD>Große</KEYWORD>
                <KEYWORD>Lieferanten</KEYWORD>
                <KEYWORD>Zentralbremssystem</KEYWORD>
                <KEYWORD>Betriebseinrichtung_2016/18_(Online)</KEYWORD>
                <KEYWORD>TPE-Rolle</KEYWORD>
                <KEYWORD>Marken</KEYWORD>
                <KEYWORD>Unsere</KEYWORD>
                <KEYWORD>TOTALSTOP,</KEYWORD>
                <KEYWORD>TOTALSTOP</KEYWORD>
            </ARTICLE_DETAILS>
        </ARTICLE>
    </T_NEW_CATALOG>
</BMECAT>

对于每篇文章,<KEYWORD>都有不同的数量。当具有相同的名称时,如何在文章中获取所有关键字?

----------------------- UPDATE ----------------------- ----------------------

现在我拥有了我需要的所有内容并最终理解。这是整个工作代码:

DROP TABLE XMLwithOpenXML

CREATE TABLE XMLwithOpenXML
(
Id INT IDENTITY PRIMARY KEY,
XMLData XML,
LoadedDateTime DATETIME
)

INSERT INTO XMLwithOpenXML(XMLData, LoadedDateTime)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
FROM OPENROWSET(BULK '\\WINSER1\\proALPHA\\templates_eBus\\Test.xml', SINGLE_BLOB) AS x;

WITH Numbered AS
(
    SELECT Id          
          ,a.value('SUPPLIER_AID[1]','nvarchar(max)') AS SUPPLIER_AID
          ,kw.value('.','nvarchar(max)') AS Keyword
    FROM XMLwithOpenXML AS t
    CROSS APPLY t.XMLData.nodes('/BMECAT/T_NEW_CATALOG/ARTICLE') AS A(a)
    CROSS APPLY a.nodes('ARTICLE_DETAILS') AS B(ad)
    CROSS APPLY ad.nodes('KEYWORD') AS C(kw)
)
SELECT Id
      ,SUPPLIER_AID
      ,KEYWORD
FROM Numbered;

非常感谢!!!

2 个答案:

答案 0 :(得分:2)

您可以将ARTICLE_DETAILS的所有节点作为单独的行。

declare @x xml= '<BMECAT>
    <T_NEW_CATALOG>
        <ARTICLE mode="new">
            <SUPPLIER_AID>9900026005</SUPPLIER_AID>
            <ARTICLE_DETAILS>
                <DESCRIPTION_SHORT>Totalstop fetra f. LF850x500mm</DESCRIPTION_SHORT>                    
                <EAN>4017976822105</EAN>
                <KEYWORD>FK_UNION</KEYWORD>
                <KEYWORD>starken</KEYWORD>
                <KEYWORD>Transport</KEYWORD>
                <KEYWORD>Große</KEYWORD>
                <KEYWORD>Lieferanten</KEYWORD>
                <KEYWORD>Zentralbremssystem</KEYWORD>
                <KEYWORD>Betriebseinrichtung_2016/18_(Online)</KEYWORD>
                <KEYWORD>TPE-Rolle</KEYWORD>
                <KEYWORD>Marken</KEYWORD>
                <KEYWORD>Unsere</KEYWORD>
                <KEYWORD>TOTALSTOP,</KEYWORD>
                <KEYWORD>TOTALSTOP</KEYWORD>
            </ARTICLE_DETAILS>
        </ARTICLE>
    </T_NEW_CATALOG>
</BMECAT>';
 select t.n.query('.')
 from @x.nodes('BMECAT/T_NEW_CATALOG/ARTICLE/ARTICLE_DETAILS/*') t(n);

修改

根据您在编辑问题中的引用,我猜您需要值,包括KEYWORD的上层和独特的兄弟。它们仍然可以从KEYWORD节点访问。

select 
    t.n.value('(/BMECAT/T_NEW_CATALOG/ARTICLE/@mode)[1]', 'varchar(50)') as mode,
    t.n.value('(/BMECAT/T_NEW_CATALOG/ARTICLE/SUPPLIER_AID)[1]', 'varchar(50)') as AID,
    t.n.value('(/BMECAT/T_NEW_CATALOG/ARTICLE/ARTICLE_DETAILS/DESCRIPTION_SHORT)[1]', 'varchar(50)') as DESCRIPTION_SHORT,
    t.n.value('(/BMECAT/T_NEW_CATALOG/ARTICLE/ARTICLE_DETAILS/EAN)[1]', 'varchar(50)') as EAN,
    t.n.value('.[1]', 'varchar(50)') as KEYWORD
 from @x.nodes('/BMECAT/T_NEW_CATALOG/ARTICLE/ARTICLE_DETAILS/KEYWORD') t(n)

答案 1 :(得分:1)

尝试这样

DECLARE @xml XML=
'<BMECAT>
    <T_NEW_CATALOG>
        <ARTICLE mode="new">
            <SUPPLIER_AID>9900026005</SUPPLIER_AID>
            <ARTICLE_DETAILS>
                <DESCRIPTION_SHORT>Totalstop fetra f. LF850x500mm</DESCRIPTION_SHORT>                    
                <EAN>4017976822105</EAN>
                <KEYWORD>FK_UNION</KEYWORD>
                <KEYWORD>starken</KEYWORD>
                <KEYWORD>Transport</KEYWORD>
                <KEYWORD>Große</KEYWORD>
                <KEYWORD>Lieferanten</KEYWORD>
                <KEYWORD>Zentralbremssystem</KEYWORD>
                <KEYWORD>Betriebseinrichtung_2016/18_(Online)</KEYWORD>
                <KEYWORD>TPE-Rolle</KEYWORD>
                <KEYWORD>Marken</KEYWORD>
                <KEYWORD>Unsere</KEYWORD>
                <KEYWORD>TOTALSTOP,</KEYWORD>
                <KEYWORD>TOTALSTOP</KEYWORD>
            </ARTICLE_DETAILS>
        </ARTICLE>
    </T_NEW_CATALOG>
</BMECAT>';
SELECT a.value('@mode','nvarchar(max)') AS ARTICLE_mode
      ,a.value('SUPPLIER_AID[1]','nvarchar(max)') AS SUPPLIER_AID
      ,ad.value('DESCRIPTION_SHORT[1]','nvarchar(max)') AS DESCRIPTION_SHORT
      ,ad.value('EAN[1]','nvarchar(max)') AS EAN
      ,kw.value('.','nvarchar(max)')
FROM @xml.nodes('/BMECAT/T_NEW_CATALOG/ARTICLE') AS A(a)
CROSS APPLY a.nodes('ARTICLE_DETAILS') AS B(ad)
CROSS APPLY ad.nodes('KEYWORD') AS C(kw)

结果

+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| ARTICLE_mode | SUPPLIER_AID | DESCRIPTION_SHORT              | EAN           | (Kein Spaltenname)                   |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | TPE-Rolle                            |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | Betriebseinrichtung_2016/18_(Online) |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | Lieferanten                          |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | Große                                |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | TOTALSTOP                            |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | starken                              |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | Unsere                               |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | Transport                            |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | TOTALSTOP,                           |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | Zentralbremssystem                   |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | FK_UNION                             |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| new          | 9900026005   | Totalstop fetra f. LF850x500mm | 4017976822105 | Marken                               |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+

更新如果您需要

这会为您带来 Great-List-of-Everything!: - )

从您关联的问题中获取更多信息......

WITH Numbered AS
(
    SELECT Id
          ,LoadedDateTime
          ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS MimeRowNr
          ,a.value('@mode','nvarchar(max)') ARTICLE_MODE
          ,a.value('SUPPLIER_AID[1]','nvarchar(max)') AS SUPPLIER_AID
          ,m.query('.') AS mime
          ,ad.query('.') AS ad
    FROM XMLwithOpenXML AS t
    CROSS APPLY t.XMLData.nodes('/BMECAT/T_NEW_CATALOG/ARTICLE') AS A(a)
    OUTER APPLY a.nodes('MIME_INFO/MIME') AS B(m)
    OUTER APPLY a.nodes('ARTICLE_DETAILS') AS C(ad)
)

SELECT Id
    ,MimeRowNr
    ,LoadedDateTime
    ,ARTICLE_MODE
    ,SUPPLIER_AID
    ,mime.value('(MIME/MIME_TYPE)[1]','nvarchar(max)') AS MIME_TYPE
    ,mime.value('(MIME/MIME_SOURCE)[1]','nvarchar(max)') AS MIME_SOURCE
    ,mime.value('(MIME/MIME_PURPOSE)[1]','nvarchar(max)') AS MIME_PURPOSE
    ,mime.value('(MIME/MIME_ORDER)[1]','int') AS MIME_ORDER
    ,ad.value('(ARTICLE_DETAILS/DESCRIPTION_SHORT)[1]','nvarchar(max)') AS DESCRIPTION_SHORT
    ,ad.value('(ARTICLE_DETAILS/EAN)[1]','nvarchar(max)') AS EAN
    ,kw.value('.','nvarchar(max)')
FROM Numbered
OUTER APPLY ad.nodes('ARTICLE_DETAILS/KEYWORD') AS D(kw)