简体   繁体   English

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

[英]How can I retrieve data from XML if all elements have the same name?

Before, please look at: 之前,请查看:

SQL-Server XML-Bulk-Import and reading as table-data SQL Server XML批量导入并读取为表数据

This is a followings question. 这是一个追随者的问题。

The 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>

For each article, there is a different number of <KEYWORD> 's. 对于每篇文章,都有不同数量的<KEYWORD> How can I get all keywords inside on article, when the have all the same Name? 当名称全部相同时,如何在文章中获取所有关键字?

-----------------------UPDATE--------------------------------------------- -----------------------更新-------------------------- -------------------

Now I have all what I need and understand finally. 现在,我拥有了我所需要的一切,并且终于了解了。 Here is the whole working code: 这是整个工作代码:

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;

Thanks a lot!!! 非常感谢!!!

You can get all nodes of ARTICLE_DETAILS as separate rows. 您可以将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);

EDIT 编辑

Following your reference in edited question i guess you need values, including upper levels and unique siblings of KEYWORD. 根据您在已编辑问题中的引用,我想您需要值,包括KEYWORD的较高级别和唯一同级。 They are still reachable from KEYWORD nodes. 从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)

Try it like this 像这样尝试

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)

The result 结果

+--------------+--------------+--------------------------------+---------------+--------------------------------------+
| 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                               |
+--------------+--------------+--------------------------------+---------------+--------------------------------------+

UPDATE If you need this 更新如果您需要此

This would bring you the Great-List-of-Everything! 这将带给您所有的东西! :-) :-)

Taken more information from your linked question... 从链接的问题中获取了更多信息...

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM