Избегайте двойного зацикливания в выходных данных API XML документов - PullRequest
0 голосов
/ 16 апреля 2020

Сначала получите CoSpaces с сервера Cisco Meeting (https: /// api / v1 / coSpaces /), где у меня более 500 коспасов. Пример XML ниже

    <?xml version="1.0"?>
<coSpaces total="500">
    <coSpace id="dfb5c48a-3354-56789-9dd1-f29a4a654230">
        <name>User A</name>
        <autoGenerated>false</autoGenerated>
        <uri>142036</uri>
        <callId>41948</callId>
    </coSpace>
    <coSpace id="18ad2a18-2e73-56789-b939-6c7cc72fbedd">
        <name>User B</name>
        <autoGenerated>false</autoGenerated>
        <uri>141113</uri>
        <callId>141113</callId>
    </coSpace>
    <coSpace id="9d28ac23-9c93-56789-949d-68960c5a5f21">
        <name>User C</name>
        <autoGenerated>false</autoGenerated>
        <uri>141137</uri>
        <callId>141137</callId>
    </coSpace>
    <coSpace id="ef340760-39e5-56789-9ed5-df76aa4ae591">
        <name>User D</name>
        <autoGenerated>false</autoGenerated>
        <uri>141114</uri>
        <callId>141114</callId>
    </coSpace>
</coSpaces>
    The second Get CoSpace details from Cisco meeting server (https://<Server 
    IP>/api/v1/coSpaces/ef340760-39e5-56789-9ed5-df76aa4ae591). Example XML as below
    <?xml version="1.0"?>
<coSpace id="ef340760-39e5-4d55-9ed5-df76aa4ae591">
    <name>User D</name>
    <autoGenerated>false</autoGenerated>
    <uri>141114</uri>
    <callId>141114</callId>
    <nonMemberAccess>true</nonMemberAccess>
    <ownerId>ca22f8b0-cdf5-56789-a0f3-932e089da4e5</ownerId>
    <ownerJid>userd@corporatexyz.com</ownerJid>
    <secret>XXXXXXXXXXXEEEEERRRR</secret>
</coSpace>

Цели: Необходимо найти все CoSpaces, где ownerjid=userd@corporatexyz.com; Мой подход: я получаю все идентификаторы и сохраняем коспасы в списке <>. позже я сделал al oop в List <> и вызвал другие методы, используя cospaceid (https: /// api / v1 / coSpaces / ef340760-39e5-56789-9ed5-df76aa4ae591). если у Cospace есть узел ownerJid, совпадает ли он с пользователем, которого я передаю? Если это совпадает, я храню в другом списке B <>. В конце покажите listb <> в виде сетки.

Проблема: это занимает слишком много времени. Что я хочу: есть ли другой способ сделать это?

Спасибо,

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

Что вам действительно нужно, так это кэшировать данные. Это занимает много времени, потому что вы должны опрашивать все каждый раз. Вот как я мог бы подойти к этой проблеме.

Создайте пару классов для структурированного хранения данных, которые вы извлекаете, а затем используйте словари для быстрого поиска проанализированных данных.

Вы может сделать что-то вроде этого:

Dictionary<Guid, CoSpace> CoSpaces = new Dictionary<Guid, CoSpace>();
OwnerDictionary Owners = new OwnerDictionary();

// Call to https://server/api/v1/coSpaces

// If persisting dictionaries instead of recreating them each time:
// List<Guid> currentCoSpaces = new List<Guid>();
foreach (<xml node enumeration>)
{
    Guid coSpaceId = Guid.Parse("id from XML");
    // If persisting dictionaries instead of recreating them each time:
    // currentCoSpaces.Add(coSpaceId);
    if (!CoSpaces.ContainsKey(coSpaceId))
    {
        // Populate the CoSpace with initial information
        CoSpace coSpace = new CoSpace
        {
            Id = coSpaceId,
            Name = "name from XML",
            AutoGenerated = Convert.ToBoolean("autoGenerated from XML"),
            Uri = Convert.ToInt32("uri from XML"),
            CallId = Convert.ToInt32("callId from XML")
        };

        // Call to https://server/api/v1/coSpaces/<guid>

        foreach (<2nd xml node enumeration>)
        {
            // Populate the CoSpace with the additional information
            coSpace.NonMemberAccess = Convert.ToBoolean("nonMemberAccess from 2nd XML");
            coSpace.Owner.Id = Guid.Parse("uri from 2nd XML");
            coSpace.Owner.Jid = "autoGenerated from 2nd XML";
            coSpace.Secret = "autoGenerated from 2nd XML";

            // Track the CoSpace
            CoSpaces.Add(coSpace.Id, coSpace);

            // Track the CoSpace Owner
            if (Owners.ContainsKey(coSpace.Owner))
                Owners[coSpace.Owner].Add(coSpace);
            else
                Owners.Add(coSpace.Owner, new List<CoSpace>() { coSpace });
        }
    }
}

// If persisting dictionaries instead of recreating them each time:
//
// Call to https://server/api/v1/coSpaces/
//
// foreach (CoSpaceOwner owner in Owners.Keys)
//     for (int index = Owners[owner].Count - 1; index >= 0; index--)
//         if (!currentCoSpaces.Contains(Owners[owner][index].Id))
//             Owners[owner].RemoveAt(index);
// 
// Guid[] coSpaceIds = new Guid[CoSpaces.Keys.Count];
// CoSpaces.Keys.CopyTo(coSpaceIds, 0);
// foreach (Guid coSpaceId in coSpaceIds)
//     if (!currentCoSpaces.Contains(coSpaceId))
//         CoSpaces.Remove(coSpaceId);


// How to retrieve an all CoSpaces that belong to the same owner by searching by Jid
List<CoSpace> ownerCoSpaces = Owners[Owners.FindOwnerByJid("someone@work.tld")];

Классы для кода выше:

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

public class CoSpace : IEquatable<CoSpace>, IComparable<CoSpace>
{
    public bool AutoGenerated { get; set; }
    public int CallId { get; set; }
    public Guid Id { get; set; }
    public string Name { get; set; }
    public bool NonMemberAccess { get; set; }
    public CoSpaceOwner Owner { get; set; }
    public string Secret { get; set; }
    public int Uri { get; set; }

    public CoSpace()
    {
        Owner = new CoSpaceOwner();
    }

    public static bool operator !=(CoSpace left, CoSpace right)
    {
        return !(left == right);
    }

    public static bool operator <(CoSpace left, CoSpace right)
    {
        return left is null ? right is object : left.CompareTo(right) < 0;
    }

    public static bool operator <=(CoSpace left, CoSpace right)
    {
        return left is null || left.CompareTo(right) <= 0;
    }

    public static bool operator ==(CoSpace left, CoSpace right)
    {
        if (left is null)
        {
            return right is null;
        }

        return left.Equals(right);
    }

    public static bool operator >(CoSpace left, CoSpace right)
    {
        return left is object && left.CompareTo(right) > 0;
    }

    public static bool operator >=(CoSpace left, CoSpace right)
    {
        return left is null ? right is null : left.CompareTo(right) >= 0;
    }

    public int CompareTo(CoSpace other)
    {
        return Id.CompareTo(other.Id);
    }

    public bool Equals(CoSpace other)
    {
        return Id.Equals(other.Id);
    }

    public override bool Equals(object other)
    {
        if (other.GetType() == typeof(CoSpace))
            return Equals((CoSpace)other);

        if (ReferenceEquals(this, other))
        {
            return true;
        }

        if (other is null)
        {
            return false;
        }

        return false;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public override string ToString()
    {
        return Name;
    }
}

public class CoSpaceOwner : IEquatable<CoSpaceOwner>, IComparable<CoSpaceOwner>
{
    public Guid Id { get; set; }
    public string Jid { get; set; }

    public static bool operator !=(CoSpaceOwner left, CoSpaceOwner right)
    {
        return !(left == right);
    }

    public static bool operator <(CoSpaceOwner left, CoSpaceOwner right)
    {
        return left is null ? right is object : left.CompareTo(right) < 0;
    }

    public static bool operator <=(CoSpaceOwner left, CoSpaceOwner right)
    {
        return left is null || left.CompareTo(right) <= 0;
    }

    public static bool operator ==(CoSpaceOwner left, CoSpaceOwner right)
    {
        if (left is null)
            return right is null;

        return left.Equals(right);
    }

    public static bool operator >(CoSpaceOwner left, CoSpaceOwner right)
    {
        return left is object && left.CompareTo(right) > 0;
    }

    public static bool operator >=(CoSpaceOwner left, CoSpaceOwner right)
    {
        return left is null ? right is null : left.CompareTo(right) >= 0;
    }

    public int CompareTo(CoSpaceOwner other)
    {
        return Id.CompareTo(other.Id);
    }

    public bool Equals(CoSpaceOwner other)
    {
        return Id.Equals(other.Id) & Jid.Equals(other.Jid);
    }

    public override bool Equals(object other)
    {
        if (other.GetType() == typeof(CoSpaceOwner))
            return Equals((CoSpaceOwner)other);

        if (ReferenceEquals(this, other))
            return true;

        if (other is null)
            return false;

        return false;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public override string ToString()
    {
        return Jid;
    }
}

[Serializable]
public class OwnerDictionary : Dictionary<CoSpaceOwner, List<CoSpace>>
{
    public OwnerDictionary()
        : base()
    {
    }

    protected OwnerDictionary(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }

    public CoSpaceOwner FindOwnerById(Guid id)
    {
        foreach (CoSpaceOwner owner in this.Keys)
            if (owner.Id.Equals(id))
                return owner;

        return null;
    }

    public CoSpaceOwner FindOwnerByJid(string jid)
    {
        foreach (CoSpaceOwner owner in this.Keys)
            if (owner.Jid.Equals(jid))
                return owner;

        return null;
    }
}
0 голосов
/ 16 апреля 2020

Используйте словарь с XML Linq:

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

namespace ConsoleApplication8
{
    class Program
    {
        const string COSPACE_FILENAME = "https:///api/v1/coSpaces/";
        const string CISCO_FILENAME = "https://<Server IP>/api/v1/coSpaces/ef340760-39e5-56789-9ed5-df76aa4ae591";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(COSPACE_FILENAME);
            XDocument docCospace = XDocument.Parse(xml);

            Dictionary<string, List<XElement>> dictCoSpace = docCospace.Descendants("coSpace")
                .GroupBy(x => (string)x.Attribute("id"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());

            xml = File.ReadAllText(CISCO_FILENAME);
            XDocument docCisco = XDocument.Parse(xml);

            Dictionary<string, List<XElement>> dictCisco = docCisco.Descendants("coSpace").Where(x => (string)x.Element("ownerjid") == "userd@corporatexyz.com")
                .GroupBy(x => (string)x.Attribute("id"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());

            var group = (from cospace in dictCoSpace
                         join cisco in dictCisco on cospace.Key equals cisco.Key
                         select new { cospace = cospace, cisco = cisco }
                         ).ToList();

        }
    }


}

Второй подход

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

namespace ConsoleApplication8
{
    class Program
    {
        const string COSPACE_FILENAME = "https:///api/v1/coSpaces/";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(COSPACE_FILENAME);
            XDocument docCospace = XDocument.Parse(xml);

            Dictionary<string, List<XElement>> dictCoSpace = docCospace.Descendants("coSpace")
                .GroupBy(x => (string)x.Attribute("id"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());


            List<KeyValuePair<XElement,List<XElement>>> pairs = new List<KeyValuePair<XElement,List<XElement>>>();
            foreach (var coSpace in dictCoSpace)
            {
                string url = string.Format("https://<Server IP>/api/v1/coSpaces/{0}", coSpace.Key);
                //get response
                string ciscoResponse = "";
                XDocument docCisco = XDocument.Parse(ciscoResponse);
                XElement cospace = docCisco.Root;

                KeyValuePair<XElement, List<XElement>> pair = new KeyValuePair<XElement, List<XElement>>(cospace, coSpace.Value);
                pairs.Add(pair);
            }
        }
    }


}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...