从文件中读取嵌套的 xml 并使用类来存储信息

问题描述 投票:0回答:1

我有一个项目,其成功标准以 xml 格式存储,然后将其与日志数据进行比较以确定构建是否成功。 xml 内容目前是这样的,但不幸的是我无法循环遍历内容以发送到我的解析日志内容,因为列表是匿名类型:

var results1 =
xmlDoc2.Descendants("build")
.SelectMany(b => b.Descendants("Process")
.Select(p => new
{
    buildMach = b.Element("BuildMachine").Value,
    p1 = p.Element("ProcessName").Value,
    startTimeHeader = p.Element("startTimeHeader").Value,
    conditions = p.Descendants("Condition")
        .Select(c => new
        {
            cName = (string)c.Attribute("name")?.Value,
            cValue = (string)c.Attribute("value")?.Value
        })
        .ToList(),
    successCriteria = p.Descendants("SuccessCriteria")
        .Select(sc => new
        {
            f1 = (string)sc.Element("field")?.Value,
            c1 = (string)sc.Element("comparison")?.Value,
            v1 = (string)sc.Element("value")?.Value
        })
        .ToList()
})).ToList();

//send to parse log method but need to find better way to get lists so not anonymous...this doesn't work:
foreach (var currentItem in results1)
{
   //string parameters except the list parameters preceded by l_
   ParseLogFile1(codeFreezeTime, currentItem.startTimeHeader, currentItem.buildMach, currentItem.p1, l_currentItem.conditions, l_currentItem.successCriteria);
}

我有新的类来尝试实现这一目标,并且我正在尝试弄清楚如何将它们与上述内容一起使用。我正在查看 linq 使用类,但我不清楚如何从 xml 获取数据以读入命名类,以便我可以访问它并发送到我的解析日志方法。

如果您想查看 xml 的样子,请参阅上一个问题中的 xml 等。

这是我想使用的课程信息:

SuccessCriterium.cs:
public class SuccessCriterium
{
   public SuccessCriterium()
      List<SuccessCriteria> successCriteria = new List<SuccessCriteria>();
}

SuccessCriteria.cs:
public class SuccessCriteria
{
    public SuccessCriteria()
    {
        string f1 = "";
        string c1 = "";
        string v1 = "";
    }
}

Condition.cs:
public class Condition
{
    public Condition()
    {
        string cName = "";
        string cValue = "";
    }
}

Conditions.cs:
public class Condition
{
    public Condition()
    {
        List<Condition> conditions = new List<Condition>();
    }
}

public class ProcessValidationInfo
{
    public ProcessValidationInfo()
    {
        string codeFreezeTime = "";
        string startTimeHeader = "";
        string buildMach = "";
        string p1 = "";
        Conditions conditions = new Conditions();
        SuccessCriterium successCriterium = new SuccessCriterium();
    }
}

我的问题是如何将从 LINQ 获取的 xml 存储在类中,以便稍后循环结果以将信息发送到我的方法时它不是匿名的?

c# list linq class
1个回答
0
投票
  1. 您的源 xml 有 2 个问题,导致 xml 在第 226 行和第 240 行损坏 其中 value=33 -> 应该是 value="33",相同的 value=8 应该是 value="8" 并且您仍然没有在提供的链接中修复它(!)

  2. 条件文件路径的值包含一个反斜杠而不是2个(一个作为转义字符)

  3. 最好的方法是序列化为json,然后从json反序列化为对象。

附注转换条件很复杂,所以我必须实现自定义转换器


void Main()
{
    XDocument doc = XDocument.Parse(File.ReadAllText("c:\\1\\file.xml"));
    string myJsonResponse = JsonConvert.SerializeXNode(doc.Root, Newtonsoft.Json.Formatting.Indented);
    Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse).Dump();
}

public class Build
{
    public string BuildMachine { get; set; }
    public List<Process> Process { get; set; }
}

public class BuildVerification
{
    public string codeFreezeTime { get; set; }
    public List<Build> build { get; set; }
}

[JsonConverter(typeof(ConditionsConverter))]
public class Conditions
{
    public List<Condition> Condition { get; set; }
    public Conditions() { Condition = new List<Condition>(); }
    
}

public class Condition
{
    public string Name { get; set; }
    public string Value { get; set; }
}

public class Process
{
    public string ProcessName { get; set; }
    public string startTimeHeader { get; set; }
    public Conditions Conditions { get; set; }
    public SuccessCriteria successCriteria { get; set; }
}

public class Root
{
    public BuildVerification BuildVerification { get; set; }
}

public class SuccessCriteria
{
    [JsonProperty("field")]
    public string field { get; set; }
    [JsonProperty("comparison")]
    public string comparison { get; set; }
    [JsonProperty("value")]
    public string value { get; set; }
    public SuccessCriteria() {}
}

class ConditionsConverter : Newtonsoft.Json.JsonConverter
{
    public override bool CanConvert(Type objectType) => objectType == typeof(Conditions);
    public override bool CanRead => true;
    public override bool CanWrite => true;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        var lst = new Conditions();
        if (reader.TokenType == JsonToken.StartObject)
        {
            reader.Read();
            while (reader.TokenType != JsonToken.EndObject)
            {
                if (reader.TokenType != JsonToken.PropertyName)
                    throw new FormatException("Expected a property name, got: " + reader.TokenType);
                string propertyName = reader.Value.ToString();
                reader.Read();
                if (propertyName == "Condition")
                {
                    if (reader.TokenType != JsonToken.StartArray)
                    {
                        var item = JObject.Load(reader);
                        lst.Condition.Add(new Condition() { Name = item.GetValue("@name").ToString(), Value = item.GetValue("@value").ToString() });
                    }
                    else
                    {
                        reader.Read();
                        var values = new List<string>();
                        while (reader.TokenType != JsonToken.EndArray)
                        {
                            if (reader.Value != null)
                                values.Add(reader.Value?.ToString());
                            reader.Read();
                        }
                        values.Chunk(4).ToList().ForEach(fe =>
                        {
                            lst.Condition.Add(new Condition() { Name = fe[1], Value = fe[3] });
                        });
                    }
                }
                reader.Read();
            }
        }
        return lst;
    }

    public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }
        var o = value as Conditions;

        JObject jo = new JObject();
        Type type = value.GetType();
        jo.Add("type", type.Name);

        jo.WriteTo(writer);
    }
}

结果

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.