使用SQL进行XML解析

时间:2017-09-04 17:27:54

标签: sql xml xml-parsing

我如何解析以下XML以获取如下名称= Business,Value = XYZ name = Product,Value = STANDARD name = Trend,Value = Active,Active New,Sparse等业务,产品,趋势数据可以是动态的,某些xml确实包含,有些则不包含,如果存在则只显示值。

你能帮我解决这个问题。

<Filter>
<Expression>
<Expression Name="Business">
<Path>
<RolePathItem>
<RoleID>Gcea34afc</RoleID>
</RolePathItem>
</Path>
<AttributeRef>
<AttributeID>3d0534a20d19</AttributeID>
</AttributeRef>
</Expression>
<Expression>
<Literal>
<DataType>String</DataType>
<Value>XYZ</Value>
</Literal>
</Expression>
</Expression>




<Expression>
<Function>
<FunctionName>Equals</FunctionName>
<Arguments>
<Expression Name="Product">
<Path>
<RolePathItem>
<RoleID>6a99c8cd92fc</RoleID>
</RolePathItem>
<RolePathItem>
<RoleID>011e01b51ba0</RoleID>
</RolePathItem>
</Path>
</Expression>
<Expression>
<Literal>
<DataType>String</DataType>
<Value>STANDARD</Value>
</Literal>
</Expression>
</Arguments>
</Function>
</Expression>



<Expression>
<Function>
<FunctionName>In</FunctionName>
<Arguments>
<Expression Name="Trend">
<Path>
<RolePathItem>
<RoleID>6a99c8cd92fc</RoleID>
</RolePathItem>
<RolePathItem>
<RoleID>dad362a5a954</RoleID>
</RolePathItem>
</Path>
</Expression>
<Expression>
<Literal>
<DataType>String</DataType>
<Values>
<Value>Active</Value>
<Value>Active New</Value>
<Value>New</Value>
<Value>Sparse</Value>
</Values>
</Literal>
</Expression>
</Arguments>
</Function>
</Expression>
</Filter>

1 个答案:

答案 0 :(得分:2)

由于动态内容,我不得不使用一些字符串函数,但它看起来很有效。

DECLARE @xmlData XML = '
<Filter>
    <Expression>
        <Expression Name="Business">
            <Path>
                <RolePathItem>
                    <RoleID>Gcea34afc</RoleID>
                </RolePathItem>
            </Path>
            <AttributeRef>
                <AttributeID>3d0534a20d19</AttributeID>
                </AttributeRef>
        </Expression>
        <Expression>
            <Literal>
                <DataType>String</DataType>
                <Value>XYZ</Value>
            </Literal>
        </Expression>
    </Expression>
    <Expression>
        <Function>
            <FunctionName>Equals</FunctionName>
            <Arguments>
                <Expression Name="Product">
                    <Path>
                        <RolePathItem>
                            <RoleID>6a99c8cd92fc</RoleID>
                        </RolePathItem>
                        <RolePathItem>
                            <RoleID>011e01b51ba0</RoleID>
                        </RolePathItem>
                    </Path>
                </Expression>
                <Expression>
                    <Literal>
                        <DataType>String</DataType>
                        <Value>STANDARD</Value>
                    </Literal>
                </Expression>
            </Arguments>
        </Function>
    </Expression>
    <Expression>
        <Function>
            <FunctionName>In</FunctionName>
            <Arguments>
                <Expression Name="Trend">
                    <Path>
                        <RolePathItem>
                            <RoleID>6a99c8cd92fc</RoleID>
                        </RolePathItem>
                        <RolePathItem>
                            <RoleID>dad362a5a954</RoleID>
                        </RolePathItem>
                    </Path>
                </Expression>
                <Expression>
                    <Literal>
                        <DataType>String</DataType>
                        <Values>
                            <Value>Active</Value>
                            <Value>Active New</Value>
                            <Value>New</Value>
                            <Value>Sparse</Value>
                        </Values>
                    </Literal>
                </Expression>
            </Arguments>
        </Function>
    </Expression>
</Filter>'

;WITH XmlRows AS (
    SELECT 
        CONVERT(VARCHAR(MAX),ref.query('*')) XMLString
    FROM @xmlData.nodes('/Filter/Expression') x ( ref )
)
,NameAndValueXml AS 
    ( SELECT CONVERT(XML, 
                SUBSTRING(XMLString, 
                    CHARINDEX('<Expression Name=',XMLString),
                    ( CHARINDEX('</Expression>',XMLString) - CHARINDEX('<Expression Name=',XMLString) + LEN('</Expression>') )  ) 
                ) AS NameXml 
            ,CONVERT(XML, 
                SUBSTRING(XMLString, 
                    CHARINDEX('<Literal>',XMLString),
                    ( CHARINDEX('</Literal>',XMLString) - CHARINDEX('<Literal>',XMLString) + LEN('</Literal>') )  ) 
                ) 
                AS ValueXml 
            FROM XmlRows
)
SELECT 
    NameXml.value('(./Expression/@Name)[1]', 'nvarchar(255)') Name, 
    CASE 
        WHEN ValueXml.exist('(/Literal/Values/*)') = 1 THEN 
            REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(max),ValueXml.query('(/Literal/Values/*)')),'</Value><Value>' , ','),'</Value>',''),'<Value>','')
        ELSE 
            ValueXml.value('(./Literal/Value)[1]', 'nvarchar(max)') 
        END AS Value
FROM NameAndValueXml

结果:

Name        Value
--------    ----------------------------
Business    XYZ
Product     STANDARD
Trend       Active,Active New,New,Sparse
相关问题