【问题标题】:Collecting XML child nodes from multiple parent nodes从多个父节点收集 XML 子节点
【发布时间】:2023-03-28 06:40:01
【问题描述】:

我正在为我正在编写的个人程序执行一些潮汐时间的网络抓取。用户输入一个港口/位置代码,它会从 UKHO 下载包含该特定港口未来 7 天潮汐时间的 HTML 网页。然后程序删除表格前后的所有 HTML 代码,留下 7 个包含潮汐数据的表格。然后它将 HTML 转换为有效的 XML 文件。这是当前程序为端口创建的 XML:

<?xml version="1.0" encoding="utf-8"?>
<Tides portID="0547" port="St. Ives">
  <Day>
    <tr>
      <th>Sat 13 Jun</th>
    </tr>
    <tr>
      <th>HW</th>
      <th>LW</th>
      <th>HW</th>
      <th>LW</th>
    </tr>
    <tr>
      <td>02:00</td>
      <td>08:35</td>
      <td>14:30</td>
      <td>21:05</td>
    </tr>
    <tr>
      <td>5.9m</td>
      <td>1.4m</td>
      <td>5.9m</td>
      <td>1.4m</td>
    </tr>
  </Day>
  <Day>
    <tr>
      <th>Wed 17 Jun</th>
    </tr>
    <tr>
      <th>HW</th>
      <th>LW</th>
      <th>HW</th>
    </tr>
    <tr>
      <td>05:17</td>
      <td>11:40</td>
      <td>17:34</td>
    </tr>
    <tr>
      <td>6.4m</td>
      <td>1.0m</td>
      <td>6.5m</td>
    </tr>
  </Day>
  <Day>
    <tr>
      <th>Sun 14 Jun</th>
    </tr>
    <tr>
      <th>HW</th>
      <th>LW</th>
      <th>HW</th>
      <th>LW</th>
    </tr>
    <tr>
      <td>02:57</td>
      <td>09:29</td>
      <td>15:23</td>
      <td>21:56</td>
    </tr>
    <tr>
      <td>6.1m</td>
      <td>1.2m</td>
      <td>6.1m</td>
      <td>1.2m</td>
    </tr>
  </Day>
</Tides>

但是我需要将其转换为如下格式:

<?xml version="1.0" encoding="utf-8"?>
<Tides portID="0547" port="St. Ives">
  <Day date="Sat 13 Jun">
    <Tides>
      <Tide type="HW" time="02:00" height="5.9m"/>
      <Tide type="LW" time="08:35" height="1.4m"/>
      <Tide type="HW" time="14:30" height="5.9m"/>
      <Tide type="LW" time="21:05" height="1.4m"/>
    </Tides>
  </Day>
  <Day date="Wed 17 Jun">
    <Tides>
      <Tide type="HW" time="05:17" height="6.4m"/>
      <Tide type="LW" time="11:40" height="1.0m"/>
      <Tide type="HW" time="17:34" height="6.5m"/>
    </Tides>
  </Day>
  <Day date="Sun 14 Jun">
    <Tides>
      <Tide type="HW" time="02:57" height="6.1m"/>
      <Tide type="LW" time="09:29" height="1.2m"/>
      <Tide type="HW" time="15:23" height="6.1m"/>
      <Tide type="LW" time="21:56" height="1.2m"/>
    </Tides>
  </Day>
</Tides>

我不知道从哪里开始将它转换为这样的格式,主要是因为代码是行而不是列(即每个标签包含列而不是行)所以我必须以某种方式计算每个迭代从每个标签中获取一个节点并将其添加到新格式的单个节点中,但我无法弄清楚如何执行此操作。更难的是一天可以包含 4,3 或 2 个潮汐(在示例中显示为第二个标签)。

我需要新格式的文件,因此文件更小,更易于阅读。如何使用 C# 将第一种格式的 XML 转换为第二种 XML 示例的格式?感谢您给我的任何帮助,我只是不知道如何将子 HW/LW、时间和高度收集到包含其中一个的集合中并将它们放入新节点中。

【问题讨论】:

  • 您是否考虑过将 XSLT 用于此类事情?它的设计正是为了做到这一点 - 将一个 XML 文件转换成另一种格式(通常是 XML 或 HTML)。

标签: c# xml


【解决方案1】:

这不是代码编写服务,但我似乎觉得有点慷慨。您想使用 LINQ to XML 进行解析,然后将数据转换为您需要的格式。此代码不处理源文件中的任何问题(例如,如果每个 &lt;tr&gt; 包含不同数量的 &lt;td&gt; 值),但它适用于您的示例:

var doc = XDocument.Parse(xml);

foreach (var day in doc.Descendants("Day"))
{
    var rows = day.Elements("tr").ToList();

    rows.Remove();

    var date = (string)rows[0].Element("th");

    day.Add(new XAttribute("date", date));

    var tides = new XElement("Tides");

    var types = rows[1].Elements().Select(e => e.Value).ToArray();
    var times = rows[2].Elements().Select(e => e.Value).ToArray();
    var heights = rows[3].Elements().Select(e => e.Value).ToArray();

    for (var i = 0; i < types.Length; i++)
    {
        tides.Add(new XElement("Tide",
            new XAttribute("type", types[i]),
            new XAttribute("time", times[i]),
            new XAttribute("height", heights[i])
            ));
    }

    day.Add(tides);
}

var result = doc.ToString();

【讨论】:

  • 非常感谢,这非常有效。同样,您提到的那个错误也不会成为问题,因为我将在问题中说(但找不到单词)每个 将始终具有相同的数字,因为每个潮汐都有时间、类型和高度。再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多