微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#:如何根据子元素的属性过滤XML文件的结果?

我可能可以用更好的标题来表述,但是我正在冒险进入从未有过的编程领域,因此我仍在学习术语.但是,这就是我想要做的:

我正在编写一个程序,可以对螺栓连接进行结构分析.但是,与其让用户每次都输入螺栓几何图形,不如让他们给他们一个从ASME统一螺纹标准(UTS)尺寸的标准列表中进行选择的选项.因此,我创建了一个Bolt类,然后创建了一个UTSBolt子类.我正在为UTS螺栓尺寸制作一个XML文件.到目前为止,我可以反序列化XML文件,将其投影到我的UTSBolts类的IEnumerable中,让用户选择一个螺栓,所有的事情都是笨拙的.

但这是我的问题

对于粗螺纹(UNC)和细螺纹(UNF)螺栓,UTS尺寸将指定螺栓的直径以及螺纹密度.因此,我已经格式化了我的XML文件,如下所示:

<Bolts_UTS>
  <Bolt>
    <Size>#0</Size>
    <MajorDiameter>0.0600</MajorDiameter>
    <ThreadDensity Series="UNF">80</ThreadDensity>
  </Bolt>
  <Bolt>
    <Size>#1</Size>
    <MajorDiameter>0.0730</MajorDiameter>
    <ThreadDensity Series="UNC">64</ThreadDensity>
    <ThreadDensity Series="UNF">72</ThreadDensity>
  </Bolt>
  <Bolt>
    <Size>#2</Size>
    <MajorDiameter>0.0860</MajorDiameter>
    <ThreadDensity Series="UNC">56</ThreadDensity>
    <ThreadDensity Series="UNF">64</ThreadDensity>
  </Bolt>
  <Bolt>
    <Size>#3</Size>
    <MajorDiameter>0.0990</MajorDiameter>
    <ThreadDensity Series="UNC">48</ThreadDensity>
    <ThreadDensity Series="UNF">56</ThreadDensity>
  </Bolt>
  <Bolt>
    <Size>#4</Size>
    <MajorDiameter>0.1120</MajorDiameter>
    <ThreadDensity Series="UNC">40</ThreadDensity>
    <ThreadDensity Series="UNF">48</ThreadDensity>
  </Bolt>
</Bolts_UTS>

用户选择螺栓尺寸时,我希望他们也能够选择螺纹系列(UNC / UNF).但是我似乎无法弄清楚如何正确设置过滤器以仅在Series属性为“ UNF”的ThreadDensity中读取.我的程序始终获取一个ThreadDensity值,而不管该属性如何.

有人可以帮我弄清楚我在做什么错吗?这是我的代码

static void Main(string[] args)
    {
        string pathCurrent = Directory.GetCurrentDirectory();
        string pathToXML = Path.GetFullPath(Path.Combine(pathCurrent, "Bolts_UTS.xml"));

        XElement boltsUTS = XElement.Load(pathToXML);
        IEnumerable<UTSBolt> boltList =
            from el in boltsUTS.Elements("Bolt")
            where (
                from thread in el.Elements("ThreadDensity")
                where
                    (string)thread.Attribute("Series") == "UNF"
                select thread).Any() &&
                ((string)el.Element("Size") == "#1")
            select new UTSBolt(
                (string)el.Element("Size"),
                (double)el.Element("MajorDiameter"),
                (double)el.Element("ThreadDensity")
            );
        Console.WriteLine("        |    Major    |");
        Console.WriteLine("UN Size\t| Dia. (inch) | Thr. / In.");
        Console.WriteLine("--------|-------------|------------");
        foreach (UTSBolt bolt in boltList)
            Console.WriteLine(bolt);

        Console.ReadLine();
    }

输出

        |    Major    |
UN Size | Dia. (inch) | Thr. / In.
--------|-------------|------------
#1      |   0.07300   |     64

解决方法:

您仅在此子查询中查看Series属性

 where (
    from thread in el.Elements("ThreadDensity")
    where
        (string)thread.Attribute("Series") == "UNF"
    select thread).Any() &&
    ((string)el.Element("Size") == "#1")

那只是检查el中的任何ThreadDensity元素是否具有正确的序列.

您实际创建UTSBolt的代码仅获得第一个ThreadDensity元素:

select new UTSBolt(
    (string)el.Element("Size"),
    (double)el.Element("MajorDiameter"),
    (double)el.Element("ThreadDensity")
);

我怀疑您想要类似的东西:

var boltList =
    from el in boltsUTS.Elements("Bolt")
    let thread = el.Elements("ThreadDensity")
                   .FirstOrDefault(t => (string) t.Attribute("Series") == "UNF")
    let size = (string) el.Element("Size")
    where thread != null && size == "#1"
    select new UTSBolt(size, (double) el.Element("MajorDiameter"), (double) thread);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。