【问题标题】:How to check condition of xml value?如何检查xml值的条件?
【发布时间】:2021-10-29 04:22:24
【问题描述】:

我想在 XML 应用程序中实现两个规则。

1 如果重量大于 10,则必须按名称部门 写:大

【问题讨论】:

  • 为什么不检查属性是否满足条件并且是否将部门字符串标记附加到结果字符串?这不是一个复杂的问题。
  • 你甚至可以内联条件检查。
  • 是的,但是为此使用一些模式会更干净。但我被困在这里了。

标签: c# xml linq-to-xml


【解决方案1】:

最好让Department 属性自己计算它的值(计算属性)。当计算发生在您期望的地方时,这更清晰,更易读。否则,在计算取决于多个属性的情况下,您会发现自己在每个参与属性中编写重复的计算代码。
因此,在请求值时执行计算——即调用计算属性的Get() 时——而不是在参与属性发生更改时。如果计算更复杂,那么遵循这个规则也会提高性能。

还要避免直接在属性的Set()/Get() 中实现这样的过滤器。将其移至方法。

我还建议使用 switch 语句或 switch 表达式,因为这比长链 if-else 块更具可读性,因此更易于维护。使用 C# 9 时,switch-expression 可以成为一个强大的过滤工​​具,具有可读性强的语法。

此外,由于您尝试为打印输出创建的字符串是实际Parcel 实例的固定string 表示,因此覆盖Parcel.ToString 会更合适。

您的 Parcel 类应如下所示:

Parcel.cs

public class Parcel
{
  public override string ToString() 
    => $"Name: {this.Name} - Postal code {this.PostalCode} - Weight {this.Weight} - Value {this.Value} - Department {this.Department}";

  public string Name { get; set; }
  public string PostalCode { get; set; }
  public decimal Weight { get; set; }
  public decimal Value { get; set; }
  public string Department => CreateDepartmentValue();

  private string CreateDepartmentValue()
  {
    var result = string.Empty;

    switch (this.Weight)
    {
      case decimal weightInKiloGrams when weightInKiloGrams <= 1: result = "Mail"; break;
      case decimal weightInKiloGrams when weightInKiloGrams <= 10: result = "Regular"; break;
      case decimal weightInKiloGrams when weightInKiloGrams > 10: result = "Heavy"; break;
    };


    switch (this.Value)
    {
      case decimal value when value > 1000: result += ", Insurance"; break;
    };

    return result;
  }
}

使用示例

public class Program
{
  static void Main(string[] args)
  {

    XDocument xdoc = XDocument.Load($"Container.xml");
    var items = ...;

    foreach (var item in items)
    {
      // Call ToString() implicitly
      Console.WriteLine(item);
      Console.WriteLine("*********************************************************************");
    }

    Console.ReadLine();
  }
}

【讨论】:

    【解决方案2】:

    您可以创建一个类 Parcel 并根据函数调用的重量和值确定部门

    public class Parcel
    {
        public string Name { get; set; }
        public string PostalCode { get; set; }
        public decimal Weight { get; set; }
        public decimal Value { get; set; }
        public string Department => GetDepartment();
        private string GetDepartment()
        {
            string _department = "";
            if (this.Weight <= 1)
            {
                _department = "Mail";
            }
            else if (this.Weight > 1 && this.Weight <= 10)
            {
                _department = "Regular";
            }
            else if (this.Weight > 10)
            {
                _department = "Heavy";
            }
            else
            {
                _department = "Unknown";
            }
    
            if (this.Value > 1000)
            {
                _department += ",Insurance";
            }
    
            return _department;
        }
    }
    

    您的XDcoument 如下所示

    XDocument xdoc = XDocument.Load($"XMLFile1.xml");
    
    var items = xdoc.Descendants("Parcel")
                    .Select(xelem => new Parcel
                    {
                        Name = xelem.Element("Sender").Element("Name").Value,
                        PostalCode = xelem.Element("Sender").Element("Address").Element("PostalCode").Value,
                        Weight = Convert.ToDecimal(xelem.Element("Weight").Value),
                        Value = Convert.ToDecimal(xelem.Element("Value").Value)
                    });
    
    foreach (var item in items)
    {
        Console.WriteLine($"{ item.Name} - { item.PostalCode} - { item.Weight} - { item.Value} - { item.Department}");
    }
    

    输出

    Klaas - 2402AE - 0.02 - 0.0 - Mail
    ykken groot B.V. - 2497GA - 2.0 - 0.0 - Regular
    seti - 2497GA - 100.0 - 2000.0 - Heavy,Insurance
    Aad - 2353HS - 11 - 500 - Heavy
    

    【讨论】:

    • 您好,谢谢。但是,如果我想再添加一个条件,例如: Department = Convert.ToDecimal(xelem.Element("Weight").Value) 1000 ? “大”:Convert.ToDecimal(xelem.Element("Weight").Value) > 10 ? “大小” });然后它不工作
    • 我没有看到邮件这个名字
    • @mightycodeNewton,我已经用更有效的方式更新了帖子
    • 嗨,克里希纳,谢谢。我更新了帖子。能不能最后看一下。我还更改了一些代码。谢谢
    • 是的,输出的第一个包裹是 2。但是 xml 中的值是 0.02
    【解决方案3】:

    为什么不扩展您的 Parcel 类,使其具有处理大小的“DepartmentSize”属性:

    class Parcel
    {
         public string DepartmentSize 
         {
             var parts = new List<string>();
             if(_Weight> 10)
                 parts.Append("Big");
             if(_Value > 1000) 
                 parts.Append("Large");
             return string.Join(",", parts);
         }
     }
    

    然后你可以像这样输出大小:

    Console.WriteLine($"... Department: {item.DepartmentSize}");
    

    【讨论】:

    • 谢谢。但这是如何连接的?我的意思是类 Parcel 目前没有使用
    • 你是对的,你的 Parcel 类没有被使用。我以为是。话虽如此,在您的程序中,为什么不创建一个 Parcels 集合(使用构造函数)而不是创建一个匿名类型,那么我的解决方案将起作用。
    • 你是说 ParcelHandler?
    猜你喜欢
    • 1970-01-01
    • 2019-02-13
    • 2015-08-11
    • 1970-01-01
    • 2018-01-31
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多