【问题标题】:How can I get children attribute + parent element如何获取子属性+父元素
【发布时间】:2021-08-19 19:31:51
【问题描述】:

我想编写一个 SQL Server 存储过程来解析 XML 数据以检索值:

DECLARE @Champs TABLE 
                (
                    NU_LINE VARCHAR(4), 
                    "KEY" VARCHAR(200), 
                    LABEL VARCHAR(200), 
                    API_NAME VARCHAR(200), 
                    API_FIELD VARCHAR(200), 
                    "VALUE" VARCHAR(MAX)
                );  

DECLARE @docHandle int;  
DECLARE @xmlDocument nvarchar(max); -- or xml type  

SET @xmlDocument = N'<STRUCTURE>
  <GRILLE>
    <ROWS>
      <ROW>
        <NU_LINE>1</NU_LINE>
        <CHAMPS>
          <CHAMP KEY="NUMBER" LABEL="AAA" API_NAME="AAA" API_FIELD="BBB" VALUE="ABC123" />
          <CHAMP KEY="RES" LABEL="AAA" API_NAME="AAA" API_FIELD="BBB" VALUE="JAMES" />
          <CHAMP KEY="DATE_BEGIN" API_NAME="CCC" API_FIELD="BBB" VALUE="14/08/2021" />
          <CHAMP KEY="DATE_END" API_NAME="CCC" API_FIELD="BBB" VALUE="28/08/2021" />
         </CHAMPS>
      </ROW>
      <ROW>
        <NU_LINE>2</NU_LINE>
        <CHAMPS>
          <CHAMP KEY="NUMBER" LABEL="ABC" API_NAME="DDD" API_FIELD="EEE" VALUE="CDE345" />
          <CHAMP KEY="DATE_RES" LABEL="CDE" API_NAME="DDD" API_FIELD="EEE" VALUE="06/05/2021" />
          <CHAMP KEY="RES" LABEL="DEF" API_NAME="DDD" API_FIELD="EEE" VALUE="JOHN" />
          <CHAMP KEY="DATE_BEGIN" API_NAME="DDD" API_FIELD="EEE" VALUE="07/08/2021" />
          <CHAMP KEY="DATE_END" API_NAME="DDD" API_FIELD="EEE" VALUE="14/08/2021" />
         </CHAMPS>
      </ROW>
      <ROW>
        <NU_LINE>3</NU_LINE>
        <CHAMPS>
          <CHAMP KEY="NUMBER" LABEL="OOO" API_NAME="FFF" API_FIELD="GGG" VALUE="EFG567" />
          <CHAMP KEY="DATE_RES" LABEL="OOO" API_NAME="FFF" API_FIELD="GGG" VALUE="10/05/2021" />
          <CHAMP KEY="RES" LABEL="OOO" API_NAME="FFF" API_FIELD="GGG" VALUE="JIM" />
          <CHAMP KEY="DATE_BEGIN" API_NAME="FFF" API_FIELD="GGG" VALUE="24/07/2021" />
          <CHAMP KEY="DATE_END" API_NAME="FFF" API_FIELD="GGG" VALUE="31/07/2021" />
         </CHAMPS>
      </ROW>
    </ROWS>
  </GRILLE>
</STRUCTURE>'

EXEC sp_xml_preparedocument @docHandle OUTPUT, @xmlDocument;  

-- Use OPENXML to provide rowset consisting of customer data.  
INSERT @Champs   
    SELECT *   
    FROM OPENXML(@docHandle, N'/STRUCTURE/GRILLE/ROWS/ROW/CHAMPS/CHAMP') 
    WITH (NU_LINE VARCHAR(4), "KEY" VARCHAR(200), LABEL VARCHAR(200), API_NAME VARCHAR(200), API_FIELD VARCHAR(200), "VALUE" VARCHAR(MAX))

SELECT * FROM @Champs

但在我的结果中NU_LIGNE 始终为空。

如何分别获取每个 ROW 的 NU_LINE 1、2 或 3?

非常感谢。

【问题讨论】:

  • 你为什么要使用那些古老的程序? SQL Server 从 2005 年开始支持 XQUERY...
  • 至于为什么,节点CHAMP没有值NU_LINE所以当然返回NULLNU_LINE 在节点 ROW 下。

标签: sql-server openxml sql-server-openxml


【解决方案1】:

正如我在 cmets 中提到的,不要使用那些旧程序;它们是为了兼容 SQL Server 2000。 SQL Server 自 2005 年以来就支持 XQUERY,因此您没有理由在 16 年后不使用它。如果你这样做,那就简单多了:

DECLARE @xmlDocument  xml; 
SET @xmlDocument = N'<STRUCTURE>
  <GRILLE>
    <ROWS>
      <ROW>
        <NU_LINE>1</NU_LINE>
        <CHAMPS>
          <CHAMP KEY="NUMBER" LABEL="AAA" API_NAME="AAA" API_FIELD="BBB" VALUE="ABC123" />
          <CHAMP KEY="RES" LABEL="AAA" API_NAME="AAA" API_FIELD="BBB" VALUE="JAMES" />
          <CHAMP KEY="DATE_BEGIN" API_NAME="CCC" API_FIELD="BBB" VALUE="14/08/2021" />
          <CHAMP KEY="DATE_END" API_NAME="CCC" API_FIELD="BBB" VALUE="28/08/2021" />
         </CHAMPS>
      </ROW>
      <ROW>
        <NU_LINE>2</NU_LINE>
        <CHAMPS>
          <CHAMP KEY="NUMBER" LABEL="ABC" API_NAME="DDD" API_FIELD="EEE" VALUE="CDE345" />
          <CHAMP KEY="DATE_RES" LABEL="CDE" API_NAME="DDD" API_FIELD="EEE" VALUE="06/05/2021" />
          <CHAMP KEY="RES" LABEL="DEF" API_NAME="DDD" API_FIELD="EEE" VALUE="JOHN" />
          <CHAMP KEY="DATE_BEGIN" API_NAME="DDD" API_FIELD="EEE" VALUE="07/08/2021" />
          <CHAMP KEY="DATE_END" API_NAME="DDD" API_FIELD="EEE" VALUE="14/08/2021" />
         </CHAMPS>
      </ROW>
      <ROW>
        <NU_LINE>3</NU_LINE>
        <CHAMPS>
          <CHAMP KEY="NUMBER" LABEL="OOO" API_NAME="FFF" API_FIELD="GGG" VALUE="EFG567" />
          <CHAMP KEY="DATE_RES" LABEL="OOO" API_NAME="FFF" API_FIELD="GGG" VALUE="10/05/2021" />
          <CHAMP KEY="RES" LABEL="OOO" API_NAME="FFF" API_FIELD="GGG" VALUE="JIM" />
          <CHAMP KEY="DATE_BEGIN" API_NAME="FFF" API_FIELD="GGG" VALUE="24/07/2021" />
          <CHAMP KEY="DATE_END" API_NAME="FFF" API_FIELD="GGG" VALUE="31/07/2021" />
         </CHAMPS>
      </ROW>
    </ROWS>
  </GRILLE>
</STRUCTURE>';

SELECT R.R.value('(NU_LINE/text())[1]','int') AS NU_LINE,
       C.C.value('@KEY','varchar(200)') AS [KEY],
       C.C.value('@LABEL','varchar(200)') AS [LABEL],
       C.C.value('@API_NAME','varchar(200)') AS [API_NAME],
       C.C.value('@API_FIELD','varchar(200)') AS [API_FIELD],
       C.C.value('@VALUE','varchar(MAX)') AS [VALUE]
FROM @xmlDocument.nodes('/STRUCTURE/GRILLE/ROWS/ROW')R(R)
     CROSS APPLY R.R.nodes('CHAMPS/CHAMP')C(C);

db<>fiddle

【讨论】:

  • 刚刚意识到它们是艺术品,而不是节点。已修复,@eric.bryan。
猜你喜欢
  • 2013-04-02
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
  • 2019-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多