XML группировка по ключу на основе другого ключа - PullRequest
0 голосов
/ 15 января 2020

У меня есть XML Документ со следующим значением. Я хочу сгруппировать по типу срочности: в этом случае я ожидаю получить Средний и 2 , поскольку слово Средний появляется только дважды, где имя Срочность .

Как я могу сделать это в C#, используя XML Linq?

<rdData>
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Incident ID" fieldId="6ae282c55e8e4266ae66ffc070c17fa3" name="IncidentID" value="590242" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Urgency" fieldId="29d741aae8bf461f8aafa3c9eb4dc822" name="Urgency" value="Medium" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="SLA Respond By Deadline" fieldId="9365b1db4ecb560c538b474ad58f51bf1fb6b101a5" name="SLARespondByDeadline" value="8/22/2019 1:54:00 PM" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="SLA Resolve By Deadline" fieldId="9365b4209be3fff3623a4a4d6ab76991c2f01ea109" name="SLAResolveByDeadline" value="8/26/2019 7:54:00 AM" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Status" fieldId="5eb3234ae1344c64a19819eda437f18d" name="Status" value="Closed" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Region" fieldId="94231bbaa05c52d6bdaa7c45cdabb090f7f9ac5318" name="Region" value="SERGN" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Owned By" fieldId="9339fc404e4c93350bf5be446fb13d693b0bb7f219" name="OwnedBy" value="Marilyn Lee" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Owned By Team" fieldId="9339fc404e8d5299b7a7c64de79ab81a1c1ff4306c" name="OwnedByTeam" value="CE BTG Support" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Service" fieldId="936725cd10c735d1dd8c5b4cd4969cb0bd833655f4" name="Service" value="BTG" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Category" fieldId="9e0b434034e94781ab29598150f388aa" name="Category" value="Application-VTS" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Subcategory" fieldId="1163fda7e6a44f40bb94d2b47cc58f46" name="Subcategory" value="General Questions" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Description" fieldId="252b836fc72c4149915053ca1131d138" name="Description" value="I need access to 8000 and 10000 Avalon for VTS. We pay for this app but I need access. Thanks." />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Close Description" fieldId="93408334d3c89b364bf3b14933a74db085d0b47824" name="CloseDescription" value="This was completed today (8/21/19) (ML)." />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Incident ID" fieldId="6ae282c55e8e4266ae66ffc070c17fa3" name="IncidentID" value="566533" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Urgency" fieldId="29d741aae8bf461f8aafa3c9eb4dc822" name="Urgency" value="Medium" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="SLA Respond By Deadline" fieldId="9365b1db4ecb560c538b474ad58f51bf1fb6b101a5" name="SLARespondByDeadline" value="4/8/2019 3:19:21 PM" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="SLA Resolve By Deadline" fieldId="9365b4209be3fff3623a4a4d6ab76991c2f01ea109" name="SLAResolveByDeadline" value="4/8/2019 3:19:21 PM" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Status" fieldId="5eb3234ae1344c64a19819eda437f18d" name="Status" value="Closed" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Region" fieldId="94231bbaa05c52d6bdaa7c45cdabb090f7f9ac5318" name="Region" value="SWRGN" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Owned By" fieldId="9339fc404e4c93350bf5be446fb13d693b0bb7f219" name="OwnedBy" value="" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Owned By Team" fieldId="9339fc404e8d5299b7a7c64de79ab81a1c1ff4306c" name="OwnedByTeam" value="CE BTG Support" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Service" fieldId="936725cd10c735d1dd8c5b4cd4969cb0bd833655f4" name="Service" value="BTG" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Category" fieldId="9e0b434034e94781ab29598150f388aa" name="Category" value="Application-VTS" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Subcategory" fieldId="1163fda7e6a44f40bb94d2b47cc58f46" name="Subcategory" value="General Questions" />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Description" fieldId="252b836fc72c4149915053ca1131d138" name="Description" value=".Do you guys handle View the Space?  Mark wants 24th @ Camelback Phases I and II added." />
  <ctCrossTab rdFlattenedElement="fields" dirty="false" displayName="Close Description" fieldId="93408334d3c89b364bf3b14933a74db085d0b47824" name="CloseDescription" value="We communicated with Melanie via email." />
</rdData>

Ответы [ 3 ]

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

Вам необходимо отфильтровать список элементов, используя метод Where, а затем вызвать метод GroupBy. В приведенном ниже примере предполагается доступ к переменной с именем xml, которая является XElement

/*
This will be an IEnumerable<XElement> with elements that
have "Urgency" as the "name" attribute.
*/
var filteredElements = xml.Elements()
    .Where(x => "Urgency".Equals(x.Attribute("name").Value));

/*
This will be an IEnumerable of key value a group with the
key "Urgency" and the value being the 2 matching elements.
*/
var groupedElements = filteredElements
    .GroupBy(x => x.Attribute("value").Value);
0 голосов
/ 15 января 2020

Я бы использовал xml linq с двойным словарем

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication149
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<string, Dictionary<string, List<XElement>>> dict = doc.Descendants("ctCrossTab")
                .GroupBy(x => (string)x.Attribute("name"), y => y)
                .ToDictionary(x => x.Key, y => y.GroupBy(a => (string)a.Attribute("value"), b => b)
                    .ToDictionary(a => a.Key, b => b.ToList()));

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

Я не уверен, правильно ли я получил вашу формулировку проблемы, посмотрите, полезен ли следующий код:

XDocument doc = XDocument.Parse("<your xml string here>");
var listElements = doc.Root.Descendants()
                        .GroupBy(t => t.Attribute("name").Value) // this is where you group by "name" attribute value
                        .Where(g => g.Key == "Urgency") // this gets you only one group where name="Urgency"
                        .SelectMany(g => g) // this will get you a IEnumerable<XElement>  with your two elements
                        ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...