【问题标题】:LINQ - get element within elementLINQ - 获取元素内的元素
【发布时间】:2017-09-13 01:03:17
【问题描述】:

我想从 XML 文件中提取信息(参见下面的特定代码部分):

<AssetsInterface>
  <Assets>
     <Asset>
       <Vehicle>
        <MaintenanceHistories>
          <MaintenanceHistory>
            <RepairDate>2014-07-02</RepairDate>
            <Mileage>30692</Mileage>
            <Dealer></Dealer>
            <Activities>
              <Activity>
                <Code></Code>
                <Description>Filtro de aceite</Description>
                <Amount>0</Amount>
              </Activity>
              <Activity>
                <Code></Code>
                <Description>Revisión 30000</Description>
                <Amount>0</Amount>
              </Activity>
            </Activities>
          </MaintenanceHistory>
          <MaintenanceHistory>
            <RepairDate>2015-03-27</RepairDate>
            <Mileage>63984</Mileage>
            <Dealer></Dealer>
            <Activities>
              <Activity>
                <Code></Code>
                <Description>Filtro de aceite</Description>
                <Amount>0</Amount>
              </Activity>
              <Activity>
                <Code></Code>
                <Description>Revisión 60000</Description>
                <Amount>0</Amount>
              </Activity>
              <Activity>
                <Code></Code>
                <Description>Escobillas</Description>
                <Amount>0</Amount>
              </Activity>
              <Activity>
                <Code></Code>
                <Description>Filtro de particulas</Description>
                <Amount>0</Amount>
              </Activity>
            </Activities>
          </MaintenanceHistory>
        </MaintenanceHistories>
      </Vehicle>
    </Asset>
  </Assets>
</AssetsInterface>

如您所见,它有多个&lt;MaintenanceHistory&gt;,其中有多个&lt;Activities&gt;。我正在寻找的输出是这样的:

2014-07-02 30692 Filtro de aceite
2014-07-02 30692 Revisión 30000
2015-03-27 63984 Filtro de aceite
2015-03-27 63984 Revisión 60000
2015-03-27 63984 Escobillas
2015-03-27 63984 Filtro de partículas

我提取&lt;RepairDate&gt;&lt;Mileage&gt; 没有问题,即使我提取了&lt;Description&gt;,但我不能一次完成。这是我目前糟糕的代码(经过 x1000 次不同的尝试......):

For Each desc As XElement In document.Descendants("Activity")
    carRepairDesc = desc.Element("Description")

    For Each options As XElement In document.Descendants("MaintenanceHistory")
        carRepairDate = options.Element("RepairDate").Value
        carRepairKMs = options.Element("Mileage").Value
    Next
    Console.WriteLine(carRepairDate & " " & carRepairKMs & "km " & carRepairDesc)
Next

这段代码的输出有点不同:

2015-12-28 96833km Filtro de aceite
2015-12-28 96833km Revisión 30000
2015-12-28 96833km Filtro de aceite
2015-12-28 96833km Revisión 60000
2015-12-28 96833km Escobillas
2015-12-28 96833km Filtro de particulas

希望您有任何建议!

编辑:

感谢@Hybridzz,这是 VB.Net 中的解决方案:

Dim document As XDocument = XDocument.Load("PATH TO XML")
Dim mHistory = From r In document.Descendants("MaintenanceHistory") Select New With {
    Key .RepairDate = r.Element("RepairDate").Value,
    Key .Mileage = r.Element("Mileage").Value,
    Key .ActivityDescs = r.Descendants("Activity").[Select](Function(x) x.Element("Description").Value)
     }

For Each r In mHistory
    For Each activityDesc In r.ActivityDescs
        Console.WriteLine(String.Format("{0} {1} {2} {3}", r.RepairDate, r.Mileage, activityDesc, Environment.NewLine))

    Next
Next

【问题讨论】:

    标签: c# xml vb.net linq


    【解决方案1】:

    这是一个 c# 版本,但您将能够更改为 VB .net

      XDocument document = XDocument.Load(@"PATH TO XML");
    
            var mHistory = from r in document.Descendants("MaintenanceHistory")
                        select new
                        {
                            RepairDate = r.Element("RepairDate").Value,
                            Mileage = r.Element("Mileage").Value,
                            ActivityDescs = r.Descendants("Activity").Select(x => x.Element("Description").Value)
                        };
    
            foreach (var r in mHistory)
            {
                foreach (var activityDesc in r.ActivityDescs)
                {
                    Console.WriteLine(string.Format("{0} {1} {2} {3}", r.RepairDate, r.Mileage, activity,  Environment.NewLine));
                }
    
            }  
    

    输出是

    2014-07-02 30692 Filtro de aceite 
    2014-07-02 30692 Revisión 30000 
    2015-03-27 63984 Filtro de aceite 
    2015-03-27 63984 Revisión 60000 
    2015-03-27 63984 Escobillas 
    2015-03-27 63984 Filtro de particulas 
    

    【讨论】:

    • 它就像一个魅力。你拯救了我的一天!你能解释一下代码吗?我不明白mHistory var 部分的工作原理。非常感谢!
    • 这就是 linq 的美妙之处,我们从 xml 数据动态地创建新对象。'select new' 将创建具有其中定义的属性的新对象。
    • 我以后肯定会用到它。再次感谢您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多