Получение неправильного имени файла, cName, cValue из xml, извлеченного с помощью linq

У меня есть проект, который считывает XML-файл ожидаемых результатов сборки для каждой области сборки и сравнивает его с журналами сборки, чтобы определить, прошла ли сборка. XML-файл, похоже, читается неправильно. Кто-нибудь знает, что не так с linq, из-за которого полученный XML-файл неверен?

Я смотрел на эти примеры: линклинк

Однако, когда я распечатываю его, чтобы проверить, прежде чем использовать, он получает неправильные значения cName и cValue. Кроме того, он всегда дает имя файла1.cs:

неправильный:

19:00
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename1.cs', field='Status', comparison='equal', value='Success'
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename1.cs', field='Status', comparison='equal', value='Success'
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename1.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinISProjectVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'

должно быть:

19:00
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename1.cs', field='Status', comparison='equal', value='Success'
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename2.cs', field='Status', comparison='equal', value='Success'
build_machine='mach31', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\R\filename3.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename4.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename5.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename6.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\D\filename7.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\K\filename8.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\K\filename9.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\K\filename11.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename22.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinFileVersionStats', condition name='VersionFile', condition value = '\\view\Build_NightlyDeveloper\K\filename33.cs', field='Status', comparison='equal', value='Success'
build_machine='mach46', process_name='SpinISProjectVersionStats', condition name='ProductName', condition value = 'P1', field='Status', comparison='equal', value='Success'

...

Пока у меня есть этот код:

void ReadXml()
{
    XmlDocument xml = new XmlDocument();
    string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    string newPath = Path.GetFullPath(Path.Combine(path, @"..\.."));
    string finalPathXml = Path.GetFullPath(Path.Combine(newPath, @"BuildVerificationBuildAttributes.xml"));

    //linq 
    XDocument xmlDoc1 = XDocument.Load(finalPathXml);
    XElement buildVerificationElement = xmlDoc1.Element("BuildVerification");
    IEnumerable<XElement> buildElements = buildVerificationElement.Elements("build");
    IEnumerable<XElement> buildMachines = buildElements.Elements("BuildMachine");

    //get just the times from the xml
    var codeFreezeTime = xmlDoc1.Descendants("codeFreezeTime").First()?.Value;
    Console.WriteLine(codeFreezeTime);

    IEnumerable<XElement> processes = buildMachines.Elements("Process");
    IEnumerable<XElement> processNames = processes.Elements("ProcessName");
    IEnumerable<XElement> conditions = processNames.Elements("Conditions");
    var found = xmlDoc1.XPathEvaluate("/BuildVerification/build/BuildMachine/Process/ProcessName/Conditions") as IEnumerable<object>;

    var results =
        xmlDoc1.Descendants("build")
        .SelectMany(x => x.Descendants("Process")
        .SelectMany(y => y.Descendants("SuccessCriteria")
        .Select(z => new
        {
            buildMach = (string)x.Element("BuildMachine"),
            p1 = (string)y.Element("ProcessName"),
            cName = (string)x.Descendants("Condition").FirstOrDefault().Attribute("name"),
            cValue = (string)x.Descendants("Condition").FirstOrDefault().Attribute("value"),
            f1 = (string)z.Element("field"),
            c1 = (string)z.Element("comparison"),
            v1 = (string)z.Element("value")
        }))).ToList();
    foreach (var cur in results)
    {
        Console.WriteLine("build_machine='{0}', process_name='{1}', condition name='{2}', condition value = '{3}', field='{4}', comparison='{5}', value='{6}'",
            cur.buildMach, cur.p1, cur.cName, cur.cValue, cur.f1, cur.c1, cur.v1);

        //get log data out to compare
        if ((cur.buildMach == "mach46") && (cur.p1 == "SpinISProjectVersionStats"))
        {
            Console.WriteLine("here"); //*at this point I see cur.cName=VersionFile which is wrong
        }
        //ParseLogFile(codeFreezeTime/*, versionChangeTime*/, cur.buildMach, cur.p1, cur.cName, cur.cValue, cur.f1, cur.c1, cur.v1);
    }

}

Вот как выглядит мой XML:

<?xml version = "1.0" encoding = "UTF-8"?>
<BuildVerification>
   <codeFreezeTime>19:00</codeFreezeTime>
   <build>
       <BuildMachine>mach31</BuildMachine>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\R\filename1.cs">
                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison> <!--can't use >= here -->
                            <value>Success</value>
                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\R\filename2.cs">
                            <SuccessCriteria>
                                <field>Status</field>
                                <comparison>equal</comparison>
                                <value>Success</value>

                            </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\R\filename3.h">
                        <SuccessCriteria>
                        <field>Status</field>
                        <comparison>equal</comparison>
                        <value>Success</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>

    </build>
    
    
    <build>
    <BuildMachine>mach46</BuildMachine>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\filename4.cs">
                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison> 
                            <value>Success</value>
                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\fiename5.h">
                            <SuccessCriteria>
                                <field>Status</field>
                                <comparison>equal</comparison>
                                <value>Success</value>

                            </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\filename6.cs">

                        <SuccessCriteria>
                        <field>Status</field>
                        <comparison>equal</comparison>
                        <value>Success</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\D\filename7.cs">
                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison> 
                            <value>Success</value>
                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\K\filename8.cs">

                            <SuccessCriteria>
                                <field>Status</field>
                                <comparison>equal</comparison>
                                <value>Success</value>

                            </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\K\filename9.h">

                        <SuccessCriteria>
                        <field>Status</field>
                        <comparison>equal</comparison>
                        <value>Success</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        
                    
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\K\filename11.cs">
                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison> <!--can't use >= here -->
                            <value>Success</value>
                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\filename22.cs">

                            <SuccessCriteria>
                                <field>Status</field>
                                <comparison>equal</comparison>
                                <value>Success</value>

                            </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinFileVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='VersionFile' value = "\\view\Build_NightlyDeveloper\K\filename33.cs">

                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison>
                            <value>Success</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        
        
        <Process>
            <ProcessName>SpinISProjectVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='ProductName' value = "P1">

                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison>
                            <value>Success</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinISProjectVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='ProductName' value = "P2">

                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison>
                            <value>Success</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>SpinISProjectVersionStats</ProcessName>
                <Conditions>
                    <Condition
                        name='ProductName' value = "P3">

                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison>
                            <value>Success</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>GetSWStats</ProcessName>
                <Conditions>
                    <Condition
                        name='DestinationPath' value = "D:\Builds\Retail\nightly">

                        <SuccessCriteria>
                            <field>UpdateRequired</field>
                            <comparison>equal</comparison>
                            <value>YES</value>

                        </SuccessCriteria>
    
                    </Condition>
                    <Condition
                        name='DestinationPath' value = "D:\Builds\Retail\nightly">

                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison>
                            <value>Successful</value>

                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        
        <Process>
            <ProcessName>ParseISLogStats</ProcessName>
                <Conditions>
                    <Condition
                        name='BuildProject' value = "RetailInstallerBuild">
                        <SuccessCriteria>
                            <field>Projects</field>
                            <comparison>equal</comparison> 
                            <value>33</value>
                        </SuccessCriteria>
                    </Condition>
                    <Condition
                        name='BuildProject' value = "RetailInstallerBuild">
                        <SuccessCriteria>
                            <field>Projects</field>
                            <comparison>equal</comparison> 
                            <value>8</value>
                        </SuccessCriteria>
                        <SuccessCriteria>
                            <field>Status</field>
                            <comparison>equal</comparison> 
                            <value>Success</value>
                        </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
        <Process>
            <ProcessName>UpdateBuildArea-Stats</ProcessName>
                <Conditions>
                    <Condition
                        name='DestPath' value = "\\mach62\Builds\nightly">

                            <SuccessCriteria>
                                <field>Dir</field>
                                <comparison>equal</comparison>
                                <value>Retail</value>

                            </SuccessCriteria>
                    </Condition>
                    <Condition
                        name='DestPath' value = "\\mach62\Builds\nightly">

                            <SuccessCriteria>
                                <field>eSecs</field>
                                <comparison>greaterThan</comparison>
                                <value>0</value>

                            </SuccessCriteria>
                    </Condition>
                </Conditions>
        </Process>
    </build>
</BuildVerification>

Похоже, вы получаете первый Condition Name/Value для содержащего build (переменная x в вашем выражении LINQ). Я считаю, что вам нужно получить первое значение, содержащее Process (переменную y в вашем LINQ). Еще лучше было бы добавить .SelectMany(process => x.Descendants("Condition")) в ваш LINQ, чтобы вы могли получить доступ к объекту условия непосредственно в дальнейшем .Select(...).

T N 09.04.2024 20:05

Изменение переменных на более значимые имена вместо x, y и z поможет улучшить читаемость. Лучше использовать такие имена, как build, process, condition и successCriteria, или даже b, p, c и sc, если вы предпочитаете короткие имена (локальные по отношению к выражению LINQ).

T N 09.04.2024 20:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Начиная с узлов SuccessCriteria, выполните навигацию вверх через свойство Parent, чтобы получить значения для cName и cValue.

var results =
    xmlDoc1.Descendants("build")
    .SelectMany(x => x.Descendants("Process")
    .SelectMany(y => y.Descendants("SuccessCriteria")
    .Select(z => new
    {
        cName = (string)z.Parent.Attribute("name"),
        cValue = (string)z.Parent.Attribute("value")
        
        // Remaining properties
        
    }))).ToList();

Ответ принят как подходящий

Похоже, вы получаете первый Condition Name/Value для содержащего build элемента (переменная x в вашем выражении LINQ). Я считаю, что вам нужно получить первый элемент, содержащий Process (переменную y в вашем LINQ). Еще лучше было бы добавить .SelectMany(process => x.Descendants("Condition") ... ) в ваш LINQ, чтобы вы могли получить доступ к элементу condition непосредственно в дальнейшем .Select(...).

Изменение переменных на более значимые имена вместо x, y и z поможет улучшить читаемость. Лучше использовать такие имена, как build, process, condition и successCriteria, или даже b, p, c и sc, если вы предпочитаете короткие мнемонические имена (при использовании локально для выражения LINQ).

Пытаться:

    var results =
        xmlDoc1.Descendants("build")
        .SelectMany(b => b.Descendants("Process")
        .SelectMany(p => p.Descendants("Condition")  // Added
        .SelectMany(c => c.Descendants("SuccessCriteria")
        .Select(sc => new
            {
                buildMach = (string)b.Element("BuildMachine"),
                p1 = (string)p.Element("ProcessName"),
                cName = (string)c.Attribute("name"),   // Simplified access
                cValue = (string)c.Attribute("value"), // Simplified access
                f1 = (string)sc.Element("field"),
                c1 = (string)sc.Element("comparison"),
                v1 = (string)sc.Element("value")
            }
        ))))
        .ToList();

У меня есть повторяющиеся разделы сборки, процесса и критериев успеха в XML.

Michele 09.04.2024 22:22

В некоторых случаях у вас также есть несколько элементов Condition на Process. (См. «ParseISLogStats» в примере данных.) Вышеупомянутое должно справиться с этим.

T N 09.04.2024 22:35

@T N, см. также мой недавний пост stackoverflow.com/questions/78343545/…

Michele 18.04.2024 14:51

Другие вопросы по теме