Как сделать запрос с несколькими связанными элементами в LINQ XML - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть следующие потомки файла XML:

    <LNodeType id="SIPROTEC5_LNType_MMXU_OpMeas_RMS_3ph_Pres" lnClass="MMXU">
        <DO name="PPV" type="SIPROTEC5_DOType_DEL_mag_V08.01.12_V08.00.00" />
        <DO name="PhV" type="SIPROTEC5_DOType_WYE_ABCRes_mag_V08.01.12_V08.00.00" />
        <DO name="A" type="SIPROTEC5_DOType_WYE_ABCRes_mag_V08.01.12_V08.00.00" />
    </LNodeType>


    <DOType id="SIPROTEC5_DOType_WYE_ABCRes_mag_V08.01.12_V08.00.00" cdc="WYE">
        <SDO name="phsA" type="SIPROTEC5_DOType_CMV_mag_without_convertions_V08.01.12_V08.00.00" />
        <SDO name="phsB" type="SIPROTEC5_DOType_CMV_mag_without_convertions_V08.01.12_V08.00.00" />
        <SDO name="phsC" type="SIPROTEC5_DOType_CMV_mag_without_convertions_V08.01.12_V08.00.00" />
    </DOType>


    <DOType id="SIPROTEC5_DOType_CMV_mag_without_convertions_V08.01.12_V08.00.00" cdc="CMV">
        <DA fc="MX" name="instCVal" bType="Struct" type="SIPROTEC5_DAType_Vector_mag_V08.01.12_V07.90.00" />
        <DA dchg="true" fc="MX" name="cVal" bType="Struct" type="SIPROTEC5_DAType_Vector_mag_V08.01.12_V07.90.00" />
    </DOType>



    <DAType id="SIPROTEC5_DAType_Vector_mag_V08.01.12_V07.90.00">
        <BDA name="mag" bType="Struct" type="SIPROTEC5_DAType_AnalogValue_FLOAT32_V08.01.12_V07.90.00" />
    </DAType>
    <DAType id="SIPROTEC5_DAType_AnalogValue_FLOAT32_V08.01.12_V07.90.00">
        <BDA name="f" bType="FLOAT32" valKind="Set">
            <Val>0</Val>
        </BDA>
    </DAType>

Каждый тип элемента является идентификатором другого потомка. Я хочу создать сплющенный список с указанием c Child. Допустим, name = "A", и результатом должен быть список:

A.phasA.instCval.f,
A.phasB.instCval.f,
A.phasC.instCval.f,
A.phasA.Cval.f,
A.phasB.Cval.f,
A.phasC.Cval.f

Я использую много внутренних объединений, но я не Я думаю, это лучший подход.

DataSet = from dataset in datasets
select new dataset()
{
Name = (string)dataset.Attribute("name"),
Lnodes = from dataAttribute in Doc.Root.Descendants(df + "DA")
join dataObject in Doc.Root.Descendants(df + "DO")
on (string)dataAttribute.Parent.Attribute("id")
equals (string)dataObject.Attribute("type")
join doi in ied.Descendants(df + "DOI")
on new
{
lnType = (string)dataObject.Parent.Attribute("id"),
lnClass = (string)dataObject.Parent.Attribute("lnClass"),
name = (string)dataObject.Attribute("name")
}

equals new
{
lnType = (string)doi.Parent.Attribute("lnType"),
lnClass = (string)doi.Parent.Attribute("lnClass"),
name = (string)doi.Attribute("name")
}

where ((string)dataAttribute.Attribute("bType") == "BOOLEAN" ||
(string)dataAttribute.Attribute("bType") == "Dbpos" ||
(string)dataAttribute.Attribute("bType") == "Struct") &
(string)dataAttribute.Attribute("name") != "origin"

select new dataset_content()
{
DoName = (string)fcda.Attribute("doName"),
DaName = (string)dataAttribute.Attribute("name")
}
}

Есть ли простой способ?

1 Ответ

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

Я бы сделал это, используя соединение.

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



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

            List<LNodeType> lNodeTypes = doc.Descendants("LNodeType")
                .SelectMany(x => x.Elements("DO")
                    .Select(y => new LNodeType() {
                        id = (string)x.Attribute("id"),
                        lnClass = (string)x.Attribute("lnClass"),
                        name = (string)y.Attribute("name"),
                        type = (string)y.Attribute("type")
                    })).ToList();

            List<DOType> doTypes = doc.Descendants("DOType")
                .SelectMany(x => x.Elements("SDO")
                    .Select(y => new DOType()
                    {
                        id = (string)x.Attribute("id"),
                        cdc = (string)x.Attribute("cdc"),
                        name = (string)y.Attribute("name"),
                        type = (string)y.Attribute("type")
                    })).ToList();

            List<DAType> daTypes = doc.Descendants("DAType")
                .SelectMany(x => x.Elements("BDA")
                    .Select(y => new DAType()
                    {
                        id = (string)x.Attribute("id"),
                        valKind = (string)y.Attribute("valKind"),
                        name = (string)y.Attribute("name"),
                        type = (string)y.Attribute("type"),
                        val = (int?)y.Descendants("Val").FirstOrDefault()
                    })).ToList();

            var results = (from l in lNodeTypes
                           join dot in doTypes on l.type equals dot.id
                           join dat in daTypes on dot.type equals dat.id into g
                           select new { lnode = l, dot = dot, dat = g }) //, dat = dat })
                          .ToList();

        }
    }
    public class LNodeType
    {
        public string id { get; set; }
        public string lnClass { get; set; }
        public string name { get; set; }
        public string type { get; set; }

    }
    public class DOType
    {
        public string id { get; set; }
        public string cdc { get; set; }
        public string name { get; set; }
        public string type { get; set; }

    }
    public class DAType
    {
        public string id { get; set; }
        public string valKind { get; set; }
        public string name { get; set; }
        public string btype { get; set; }
        public string type { get; set; }
        public int? val { get; set; }

    }

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