CROSS APPLY to namespace, sub nodes returns duplicate records

天大地大妈咪最大 提交于 2019-12-11 05:08:46

问题


I have this xml (removed most of it for readability). I get wrong records. Wrong chemical names fetched for every CAS_Number. One CAS_Number means one chemical. But here, for the same CAS_number, I have different chemical names.

It's the problem in my cross apply but I couldn't figure it out.

<ArrayOfCatalogItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CatalogItem Version="1">
   <Msds xmlns="http://3ecompany.com/webservices/catalogitemxml">
     <ProductIdentifiers xmlns="http://3ecompany.com/webservices/catalogitemxml">
      <Identifier>M007628</Identifier>
      <Source>CPN</Source>
      <FirstExportDate xsi:nil="true" />
      <LastExportDate xsi:nil="true" />
      <FlaggedForResend xsi:nil="true" />
    </ProductIdentifiers>
     <Ingredients>
        <ChemicalName>Hexane</ChemicalName>
        <Cas>000110-54-3</Cas>
        <AvgPercent>20.000000</AvgPercent>
      </Ingredients>
      <Ingredients>
        <ChemicalName>2-Propanone</ChemicalName>
        <Cas>000067-64-1</Cas>
        <AvgPercent>20.000000</AvgPercent>
      </Ingredients>
      <Ingredients>
        <ChemicalName>Petroleum gases, liquefied, sweetened</ChemicalName>
        <Cas>068476-86-8</Cas>
      </Ingredients>
  </Msds>
</CatalogItem>
</ArrayOfCatalogItem>

The stored procedure goes like this:

DECLARE @XmlTable TABLE (XMLDATA XML)

INSERT INTO @XmlTable(XMLData)
    SELECT CONVERT(XML, BulkColumn) AS BulkColumn 
    FROM OPENROWSET(BULK 'C:\AA.Sample.File.LUS.Pilly-oneCI.xml', SINGLE_BLOB) AS x;

;WITH XMLNAMESPACES ('http://3ecompany.com/webservices/catalogitemxml' as CI)
SELECT 
    --CIVersion = CI.value('@Version', 'int'),
    Identifier = PID.value('(.)\[1\]', 'varchar(9)'),
    Product_Name = MSDSPN.value('(.)\[1\]','varchar(100)'),
    CAS_Number = CAS.value('(.)\[1\]', 'varchar(20)'),
    Chemical_Name = CN.value('(.)\[1\]', 'varchar(100)')

FROM
    @XmlTable
CROSS APPLY
    XMLData.nodes('/ArrayOfCatalogItem/CatalogItem') AS XT(CI)
OUTER APPLY
    CI.nodes('CI:ProductIdentifiers/CI:Identifier') AS XT2(PID)
CROSS APPLY
    CI.nodes('CI:Msds/CI:Ingredients/CI:Cas') AS XT18(CAS)
CROSS APPLY
    CI.nodes('CI:Msds/CI:Ingredients/CI:ChemicalName') AS XT19(CN)

回答1:


Try this:

;WITH XMLNAMESPACES ('http://3ecompany.com/webservices/catalogitemxml' as CI)
SELECT 
    Identifier = CI.value('(CI:ProductIdentifiers[1]/CI:Identifier)[1]', 'varchar(9)'),
    CAS_Number = Ingred.value('(CI:Cas)[1]', 'varchar(20)'),
    Chemical_Name = Ingred.value('(CI:ChemicalName)[1]', 'varchar(100)')
FROM
    @XmlTable
CROSS APPLY
    XMLData.nodes('/ArrayOfCatalogItem/CatalogItem/CI:Msds') AS XT(CI)
CROSS APPLY
    CI.nodes('CI:Ingredients') AS XT18(Ingred)

I get a list of XML fragments for each <Msds> node, and from this I grab the ProductIdentifiers info. Plus, from this node, I also get a list of sub-XML-fragments for the <Ingredients> nodes, and grab detailed into from these.

My output looks like this:



来源:https://stackoverflow.com/questions/39293745/cross-apply-to-namespace-sub-nodes-returns-duplicate-records

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!