【问题标题】:Getting multiple XML values from SQL从 SQL 获取多个 XML 值
【发布时间】:2020-01-28 11:22:06
【问题描述】:

我有一个名为“视图”的表,其中包含从 Microsoft 服务管理器数据库中提取的数据。为了简化这个问题,我会说这个表有 2 列:

Views
----------
ViewId    (uniqueidentifier)
ConfigXML (xml)

XML 数据示例如下:

<Data>
  <Adapters>
    <Adapter AdapterName="dataportal:EnterpriseManagementObjectProjectionAdapter">
      <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>
      <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.EnterpriseManagementObjectProjectionAdapter</AdapterType>
    </Adapter>
    <Adapter AdapterName="viewframework://Adapters/AdvancedList">
      <AdapterAssembly>Microsoft.EnterpriseManagement.UI.ViewFramework</AdapterAssembly>
      <AdapterType>Microsoft.EnterpriseManagement.UI.ViewFramework.AdvancedListSupportAdapter</AdapterType>
    </Adapter>
    <Adapter AdapterName="omsdk://Adapters/Criteria">
      <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>
      <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.SdkCriteriaAdapter</AdapterType>
    </Adapter>
  </Adapters>
  <ItemsSource>
    <AdvancedListSupportClass xmlns="clr-namespace:Microsoft.EnterpriseManagement.UI.ViewFramework;assembly=Microsoft.EnterpriseManagement.UI.ViewFramework" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" DataTypeName="" AdapterName="viewframework://Adapters/AdvancedList" FullUpdateAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" DataSource="mom:ManagementGroup" FullUpdateFrequency="100" Streaming="true" IsRecurring="true" RecurrenceFrequency="{x:Static s:Int32.MaxValue}" UpdateItemsAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" AppendItemsAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" RemoveItemsAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter">
      <AdvancedListSupportClass.Parameters>
        <QueryParameter Parameter="TypeProjectionId" Value="$MPElement[Name='IncidentManagement!System.WorkItem.Incident.ProjectionType']$" />
      </AdvancedListSupportClass.Parameters>
    </AdvancedListSupportClass>
  </ItemsSource>
  <Criteria>
    <QueryCriteria xmlns="http://tempuri.org/Criteria.xsd" Adapter="omsdk://Adapters/Criteria">
      <Criteria>
        <FreeformCriteria>
          <Freeform>
            <Criteria xmlns="http://Microsoft.EnterpriseManagement.Core.Criteria/">
              <Expression>
                <And>
                  <Expression>
                    <Or>
                      <Expression>
                        <SimpleExpression>
                          <ValueExpressionLeft>
                            <Property>$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
                          </ValueExpressionLeft>
                          <Operator>Equal</Operator>
                          <ValueExpressionRight>
                            <Value>{5e2d3932-ca6d-1515-7310-6f58584df73e}</Value>
                          </ValueExpressionRight>
                        </SimpleExpression>
                      </Expression>
                      <Expression>
                        <SimpleExpression>
                          <ValueExpressionLeft>
                            <Property>$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
                          </ValueExpressionLeft>
                          <Operator>Equal</Operator>
                          <ValueExpressionRight>
                            <Value>{b6679968-e84e-96fa-1fec-8cd4ab39c3de}</Value>
                          </ValueExpressionRight>
                        </SimpleExpression>
                      </Expression>
                    </Or>
                  </Expression>
                  <Expression>
                    <Or>
                      <Expression>
                        <SimpleExpression>
                          <ValueExpressionLeft>
                            <Property>$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/TierQueue$</Property>
                          </ValueExpressionLeft>
                          <Operator>Equal</Operator>
                          <ValueExpressionRight>
                            <Value>{e41fea6c-90fa-4c6d-48fb-6d90ef3e8348}</Value>
                          </ValueExpressionRight>
                        </SimpleExpression>
                      </Expression>
                      <Expression>
                        <SimpleExpression>
                          <ValueExpressionLeft>
                            <Property>$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/TierQueue$</Property>
                          </ValueExpressionLeft>
                          <Operator>Equal</Operator>
                          <ValueExpressionRight>
                            <Value>{bfe405d7-11f3-09cc-882f-709b5505849d}</Value>
                          </ValueExpressionRight>
                        </SimpleExpression>
                      </Expression>
...

特别是,我对“表达式”节点感兴趣。我正在尝试从 Expression/SimpleExpression/ValueExpressionLeft/Value 中提取值,但仅在 Expression/SimpleExpression/ValueExpressionRight/Property 包含文本“TierQueue”的地方。

与此匹配的表达式节点的数量会有所不同。一些 ConfigXML 值只有一个匹配的条目,其他的有多达 10 个条目。我需要所有的匹配。

决赛桌应该是这样的:

ViewID                                  TierQueue
----------------                        -----------------
3CC97021-1C04-64BB-6391-00A48C07AB41    20ad0c6e-a41d-aab9-cc16-ae6e5efe45d8
08EA4E4C-ED4B-7E56-E257-04717A7289E8    e3d37f4a-3ccd-1abd-3180-9b439616ce43
1502A994-5A82-E6C9-E278-05569CC929C9    0fa5f999-4d19-3a72-a0c4-ff48db2bfdd8
1502A994-5A82-E6C9-E278-05569CC929C9    666d6236-0deb-4c8f-0922-9e44245d692e
F0301A91-C6B6-E332-7F82-06DC59352D93    dbff58a6-d7f0-4b15-33d4-e2b0edbd6fe8
F0301A91-C6B6-E332-7F82-06DC59352D93    f9ba3c86-d6f5-f91d-98aa-10db1f9d054d

到目前为止我做了什么

我承认,我以前从未使用过 XML,所以我所做的尝试相当于尝试从网上的示例中拼凑出一些东西。

这是我所知道的:

SELECT
ViewID,
n.p.value('(//*[local-name()="Value"]/text())[1]', 'nvarchar(max)') as TierQueueID
FROM views smv
CROSS APPLY smv.ConfigurationXML.nodes('(//*[local-name()="SimpleExpression"])') as n (p)

不幸的是,这给了我错误的结果。它只是在每个 XML 文档中第一次出现“值”,然后复制几次

【问题讨论】:

    标签: sql-server xquery-sql


    【解决方案1】:

    灵感:

    declare @x xml = N'
    <Data>
      <Adapters>
        <Adapter AdapterName="dataportal:EnterpriseManagementObjectProjectionAdapter">
          <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>
          <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.EnterpriseManagementObjectProjectionAdapter</AdapterType>
        </Adapter>
        <Adapter AdapterName="viewframework://Adapters/AdvancedList">
          <AdapterAssembly>Microsoft.EnterpriseManagement.UI.ViewFramework</AdapterAssembly>
          <AdapterType>Microsoft.EnterpriseManagement.UI.ViewFramework.AdvancedListSupportAdapter</AdapterType>
        </Adapter>
        <Adapter AdapterName="omsdk://Adapters/Criteria">
          <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>
          <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.SdkCriteriaAdapter</AdapterType>
        </Adapter>
      </Adapters>
      <ItemsSource>
        <AdvancedListSupportClass xmlns="clr-namespace:Microsoft.EnterpriseManagement.UI.ViewFramework;assembly=Microsoft.EnterpriseManagement.UI.ViewFramework" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" DataTypeName="" AdapterName="viewframework://Adapters/AdvancedList" FullUpdateAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" DataSource="mom:ManagementGroup" FullUpdateFrequency="100" Streaming="true" IsRecurring="true" RecurrenceFrequency="{x:Static s:Int32.MaxValue}" UpdateItemsAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" AppendItemsAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter" RemoveItemsAdapter="dataportal:EnterpriseManagementObjectProjectionAdapter">
          <AdvancedListSupportClass.Parameters>
            <QueryParameter Parameter="TypeProjectionId" Value="$MPElement[Name=''IncidentManagement!System.WorkItem.Incident.ProjectionType'']$" />
          </AdvancedListSupportClass.Parameters>
        </AdvancedListSupportClass>
      </ItemsSource>
    
        <Criteria>
        <QueryCriteria xmlns="http://tempuri.org/Criteria.xsd" Adapter="omsdk://Adapters/Criteria">
          <Criteria>
            <FreeformCriteria>
              <Freeform>
                <Criteria xmlns="http://Microsoft.EnterpriseManagement.Core.Criteria/">
                  <Expression>
                    <And>
                      <Expression>
                        <Or>
                          <Expression>
                            <SimpleExpression>
                              <ValueExpressionLeft>
                                <Property>$Context/Property[Type=''CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident'']/Status$</Property>
                              </ValueExpressionLeft>
                              <Operator>Equal</Operator>
                              <ValueExpressionRight>
                                <Value>{5e2d3932-ca6d-1515-7310-6f58584df73e}</Value>
                              </ValueExpressionRight>
                            </SimpleExpression>
                          </Expression>
                          <Expression>
                            <SimpleExpression>
                              <ValueExpressionLeft>
                                <Property>$Context/Property[Type=''CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident'']/Status$</Property>
                              </ValueExpressionLeft>
                              <Operator>Equal</Operator>
                              <ValueExpressionRight>
                                <Value>{b6679968-e84e-96fa-1fec-8cd4ab39c3de}</Value>
                              </ValueExpressionRight>
                            </SimpleExpression>
                          </Expression>
                        </Or>
                      </Expression>
                      <Expression>
                        <Or>
                          <Expression>
                            <SimpleExpression>
                              <ValueExpressionLeft>
                                <Property>$Context/Property[Type=''CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident'']/TierQueue$</Property>
                              </ValueExpressionLeft>
                              <Operator>Equal</Operator>
                              <ValueExpressionRight>
                                <Value>{e41fea6c-90fa-4c6d-48fb-6d90ef3e8348}</Value>
                              </ValueExpressionRight>
                            </SimpleExpression>
                          </Expression>
                          <Expression>
                            <SimpleExpression>
                              <ValueExpressionLeft>
                                <Property>$Context/Property[Type=''CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident'']/TierQueue$</Property>
                              </ValueExpressionLeft>
                              <Operator>Equal</Operator>
                              <ValueExpressionRight>
                                <Value>{bfe405d7-11f3-09cc-882f-709b5505849d}</Value>
                              </ValueExpressionRight>
                            </SimpleExpression>
                          </Expression>
                        </Or>
                      </Expression>
                    </And>
                  </Expression>
                </Criteria>
                </Freeform>
                </FreeformCriteria>
               </Criteria>
            </QueryCriteria>
           </Criteria>
    </Data>
    ';
    
    declare @views table(viewid int, ConfigurationXML xml);
    
    insert into @views(viewid, ConfigurationXML)
    values (1, @x);
    --------------------------------------------------------------
    
    SELECT
    ViewID,
    n.p.value('local-name(.)', 'varchar(50)') as nodename,
    n.p.value('declare default element namespace "http://Microsoft.EnterpriseManagement.Core.Criteria/"; (ValueExpressionRight/Value)[1]', 'nvarchar(max)') as TierQueueID
    FROM @views smv
    CROSS APPLY smv.ConfigurationXML.nodes('
    declare default element namespace "http://Microsoft.EnterpriseManagement.Core.Criteria/";
    //SimpleExpression[contains((ValueExpressionLeft/Property/text())[1], "TierQueue")]') as n (p);
    
    
    WITH XMLNAMESPACES (DEFAULT 'http://Microsoft.EnterpriseManagement.Core.Criteria/')  
    SELECT
    ViewID,
    n.p.value('local-name(.)', 'varchar(50)') as nodename,
    n.p.value('(ValueExpressionRight/Value)[1]', 'nvarchar(max)') as TierQueueID
    FROM @views smv
    CROSS APPLY smv.ConfigurationXML.nodes('//SimpleExpression[ValueExpressionLeft/Property[contains(text()[1], "TierQueue")]]') as n (p);
    

    【讨论】:

    • 他们工作出色 - 谢谢!请提出两个问题......local-name(.) 究竟做了什么?在这一行中:n.p.value('(ValueExpressionRight/Value)[1]', 'nvarchar(max)') 为什么以及如何从 ValueExpressionRight 节点开始路径?到目前为止,我遇到的所有示例都暗示我必须输入完整路径回到根目录。如果这些问题看起来很愚蠢,我们深表歉意。
    • local-name() 返回节点的名称。 local-name(.) = 当前节点的名称。您使用的交叉应用也是如此: //*[local-name()=xyz] ==any node ,在任何级别,其名称为 xyz (在 filter[] current 内。“dot”是隐含的) .选择/查询中不需要整个值(local-name(.))。
    • 路径从 ConfigurationXML.nodes(//SimpleExpression) ==任何 SimpleExpression 节点(命名空间..过滤/具有 ValueExpressionLeft 和属性 abc)返回的“片段”“开始”。每个片段将是 .....。您可以通过将选择部分 ....nodename, n.p.query('.') 作为 xmlfragment, .... 来获取每个 node() 的片段
    • 这真的很有帮助,谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多