Shredding XML From Execution Plans

后端 未结 2 1195
春和景丽
春和景丽 2020-12-04 00:10

I\'ll preface this by saying that I hate XML, horrible stuff to work with, but necessary sometimes.

My current issue is that I\'m trying to take the XML from an exec

2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-04 00:58

    A very straight way could be this (while @x is your XML-execution-plan):

    DECLARE @x XML=
    N'
        E1-Text 2
        E1-Text 2
        
          
          Free text
        
      ';
    
    DECLARE @idoc INT;
    EXEC sp_xml_preparedocument @idoc OUTPUT, @x;   
    SELECT * FROM OPENXML (@idoc, '*');   
    EXEC sp_xml_removedocument @idoc;  
    

    The result (not all columns)

    +----+----------+----------+--------------+------+--------------------------+
    | id | parentid | nodetype | localname    | prev | text                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 0  | NULL     | 1        | root         | NULL | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 2  | 0        | 1        | ElementE1    | NULL | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 3  | 2        | 2        | AttributA1   | NULL | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 13 | 3        | 3        | #text        | NULL | A1-text belongs to E1[1] |
    +----+----------+----------+--------------+------+--------------------------+
    | 4  | 2        | 2        | OneMore      | NULL | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 14 | 4        | 3        | #text        | NULL | xyz                      |
    +----+----------+----------+--------------+------+--------------------------+
    | 5  | 2        | 3        | #text        | NULL | E1-Text 2                |
    +----+----------+----------+--------------+------+--------------------------+
    | 6  | 0        | 1        | ElementE1    | 2    | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 7  | 6        | 2        | AttributA1   | NULL | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 15 | 7        | 3        | #text        | NULL | A1-text belongs to E1[2] |
    +----+----------+----------+--------------+------+--------------------------+
    | 8  | 6        | 3        | #text        | NULL | E1-Text 2                |
    +----+----------+----------+--------------+------+--------------------------+
    | 9  | 0        | 1        | ElementParent| 6    | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 10 | 9        | 1        | subElement   | NULL | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 11 | 10       | 2        | test         | NULL | NULL                     |
    +----+----------+----------+--------------+------+--------------------------+
    | 16 | 11       | 3        | #text        | NULL | sub                      |
    +----+----------+----------+--------------+------+--------------------------+
    | 12 | 9        | 3        | #text        | 10   | Free text                |
    +----+----------+----------+--------------+------+--------------------------+
    

    The id shows clearly, that the algorithm is breadth first, there is no id=1 (why ever) and the nodetype allows to distinguish between elements, attributs and (floating) text. The prev column points to a sibling up in the chain. The missing columns are related to namespaces...

    The approach with FROM OPENXML is outdated, but this is one of the rare situations it might still be very usefull...

    You get a list with IDs and ParentIDs you might query with an recursive CTE... This depends on what you want to do with this afterwards...

提交回复
热议问题