c# - 解析 XML 文件时出现问题

标签 c# .net wpf xml

我有以下 XML 文件:

<?xml version="1.0" encoding="utf-8" ?>
<strategies>

  <strategy name="God Class">
    <gate type="AND">
      <rule>
        <metric>LOC</metric>
        <comparison>greater than</comparison>
        <value>850</value>
      </rule>
      <rule>
        <metric>FANIN</metric>
        <comparison>greater than</comparison>
        <value>850</value>
      </rule>
      <rule>
        <metric>FANOUT</metric>
        <comparison>greater than</comparison>
        <value>850</value>
      </rule>
    </gate>
  </strategy>

  <strategy name="TClass">
    <gate type="OR">
      <gate type="AND">
        <rule>
          <metric>LOC</metric>
          <comparison>greater than</comparison>
          <value>100</value>
        </rule>
        <rule>
          <metric>NOM</metric>
          <comparison>greater than</comparison>
          <value>200</value>
        </rule>
      </gate>
      <rule>
        <metric>NOPAR</metric>
        <comparison>greater than</comparison>
        <value>300</value>
      </rule>
    </gate>
  </strategy>

</strategies>

现在我尝试解析这个文档并提取规则。第一种策略很容易使用以下代码:

public static void parseRules()
        {
            XDocument document = XDocument.Load(FILE);
            XElement root = document.Root;

            foreach (XElement elem in root.Elements())
            { 
                String name = elem.Attribute(STRATEGY_NAME).Value;
                XElement gate = elem.Element(GATE_NAME);

                List<Rule> rules = new List<Rule>();
                foreach (XElement r in gate.Elements())
                {
                        String metric = r.Element(METRIC_NAME).Value;
                        String comparisation = r.Element(COMPARISON_NAME).Value;
                        int threshold = Convert.ToInt32(r.Element(VALUE_NAME).Value);

                        Rule rule = null;

                        if (comparisation.Equals(GREATER_THAN_NAME))
                        {
                            rule = new Rule(metric, Rule.GREATHER_THAN, threshold);
                        }
                        else if (comparisation.Equals(SMALLER_THAN_NAME))
                        {
                            rule = new Rule(metric, Rule.SMALLER_THAN, threshold);
                        }
                        rules.Add(rule);   
                }
                ISpecification spec = rules.ElementAt(0);
                if (gate.Attribute(TYPE_NAME).Value.Equals(AND))
                {
                    for (int i = 1; i < rules.Count; i++)
                    {
                        spec = spec.And(rules.ElementAt(i));
                    }
                }
                else if (gate.Attribute(TYPE_NAME).Value.Equals(OR))
                {
                    for (int i = 1; i < rules.Count; i++)
                    {
                        spec = spec.Or(rules.ElementAt(i));
                    }   
                }
                DetectionStrategy strategy = new DetectionStrategy(spec, name);
            }
        }
    }

显然,这仅适用于仅在一个门中具有规则而在第二个示例中没有另一个门的 XML 文件。但是我无法解析嵌套的门。有什么从哪里开始的提示吗?

最佳答案

使用 XDocument 或 XmlDocument 解析 XML 会很脆弱。

我建议您设计一个对象模型来满足这种结构和逻辑,并使用XML 序列化/反序列化 来持久化或水化。

归根结底,这种 XML 表示形式只是您逻辑的一种可能表示形式,您可以将它们作为 JSON、二进制......

一个例子:

public class Strategy
{
    [XmlAttribute]
    public string Name {get; set;}

    [XmlElement("Gate")]
    public Gate MainGate {get; get}
}
/// ...........

public class Gate
{

    XmlElement("Gate")
    public Gate ChildGate {get; set;}
    // ...
}    

更新

这是序列化的方式(简单易行)

XmlSerializer xs = new XmlSerializer(typeof(Strategy));
FileStream fs = new FileStream("strategy.xml", FileMode.Create);
xs.Serialize(fs, myStrategy);

关于c# - 解析 XML 文件时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4571263/

相关文章:

c# - 按钮边框在 XAML/C# 中被切断

c# - .NetCoreApp 和 .NetStandard.Library 有什么区别?

c# - 在 LINQ 选择中使用公式

c# - 如何在 C# 中获取 Hotmail 联系人列表?

.net - 无法序列化作为 DataSet 一部分的 DataTable

c# - XAML 在不改变颜色的情况下改变背景不透明度

.net - 用于 WPF 富客户端应用程序的图像编辑器组件

c# - 将 C 结构与 union 编码到 C# 代码时获取垃圾数据

c# - 在 winforms TreeView 中设置第一个节点的位置/边距

ASP.Net 还是 WPF (C#)?