Получение нескольких значений XML из SQL - PullRequest
0 голосов
/ 28 января 2020

У меня есть таблица с именем 'views', содержащая данные, извлеченные из базы данных Microsoft Service Manager. Чтобы упростить этот вопрос, я скажу, что в этой таблице 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'.

Количество узлов выражений, соответствующих этому, варьируется. Некоторые из значений Config XML имеют только одну соответствующую запись, другие имеют до 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

Что я уже сделал

I Признаюсь, я никогда раньше не работал с XML, и поэтому я пытался собрать воедино все из примеров на net.

Это примерно столько, сколько я получил:

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)

, что, к сожалению, дает мне неправильные результаты. Он просто получает первое значение «Value» в каждом XML документе, а затем дублирует его несколько раз

1 Ответ

0 голосов
/ 28 января 2020

Для вдохновения:

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);
...