xml.value-动态路径包含斜杠字符的问题

时间:2019-02-18 08:30:40

标签: xml tsql

当我想在其中使用带有斜杠字符的动态路径时,在xml.value中达到xml中的值时遇到问题。在我的外部服务应用程序中,我收到两种XML,但是唯一的区别是两个“根”节点,其余XML相同。

第一种XML:

<CreditInquiryResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<creditReport>
    <reportHeader>  
        <userId>USERNAME1</userId>
        -- some other nodes
    </reportHeader>
    -- some other nodes
</creditReport>

第二种类型:

<BIKReportResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ReportObject>
    <reportHeader>  
        <userId>USERNAME1</userId>
        -- some other nodes
    </reportHeader>
    -- some other nodes  
    </reportHeader>
</ReportObject>

当我试图获得一些价值时,例如userId,我正在根据XML类型使用动态路径:

    SELECT 
    @type1 = @xml.exist('(/CreditInquiryResponse/creditReport/processingResult)'),
    @type2 = @xml.exist('(/BIKReportResult/ReportObject/processingResult)')

然后我正在构建路径,这是我的问题。当它由两部分构成,然后直接在xml.value中用斜杠字符分开时,它就可以工作了,并且我正在获得userId值。

if(@type1 = 1)
begin
    SET @reportPathFirstPart = 'CreditInquiryResponse'
    SET @reportPathSecondPart = 'creditReport'
end

if(@type2 = 1)
begin
    SET @reportPathFirstPart = 'BIKReportResult'
    SET @reportPathSecondPart = 'ReportObject'
end

SELECT @userId = @xml.value('(/*[local-name()=sql:variable("@reportPathFirstPart")]/*[local-name()=sql:variable("@reportPathSecondPart")]/reportHeader/userId)[1]','varchar(max)') 

但是,当我尝试将其串联为一个变量时,它将不起作用,并且我将NULL作为userId值。

SET @reportPath = @reportPathFirstPart + '/' + @reportPathSecondPart

SELECT @userId = @xml.value('(/*[local-name()=sql:variable("@reportPath")]/reportHeader/userId)[1]','varchar(max)') 

有人知道为什么吗?也许这是获得像这样的动态路径的更好的方法?

1 个答案:

答案 0 :(得分:1)

如果我正确理解了这一点,那么您正在寻找<reportHeader>中的节点,但是此节点不是位于同一嵌套结构中吗?您可以通过使用双斜杠开始Xpath来使用深度搜索

SELECT @xml.value('(//reportHeader/userId/text())[1]','nvarchar(100)');

阅读为:在任何地方找到<reportHeader>

如果您知道有两个名称不同的级别,则可以执行以下操作:

SELECT @xml.value('(/*/*/reportHeader/userId/text())[1]','nvarchar(100)')

阅读为:打开根节点和下面的任何节点,并在其中找到<reportHeader>

另一种方法是搜索存在子节点reportHeader的任何节点。您可以选择reportHeader中的信息,也可以选择此节点下的任何其他信息:

SELECT @xml.value('(//*[reportHeader]/reportHeader/userId/text())[1]','nvarchar(100)')

读取为::查找XML中具有子节点<reportHeader>的任何节点。从那里开始。