У меня есть проект, который считывает 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>
Изменение переменных на более значимые имена вместо x
, y
и z
поможет улучшить читаемость. Лучше использовать такие имена, как build
, process
, condition
и successCriteria
, или даже b
, p
, c
и sc
, если вы предпочитаете короткие имена (локальные по отношению к выражению LINQ).
Начиная с узлов 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.
В некоторых случаях у вас также есть несколько элементов Condition
на Process
. (См. «ParseISLogStats» в примере данных.) Вышеупомянутое должно справиться с этим.
@T N, см. также мой недавний пост stackoverflow.com/questions/78343545/…
Похоже, вы получаете первый
Condition Name/Value
для содержащегоbuild
(переменнаяx
в вашем выражении LINQ). Я считаю, что вам нужно получить первое значение, содержащееProcess
(переменнуюy
в вашем LINQ). Еще лучше было бы добавить.SelectMany(process => x.Descendants("Condition"))
в ваш LINQ, чтобы вы могли получить доступ к объекту условия непосредственно в дальнейшем.Select(...)
.