处理两个 XML 文档以查找结果

本文关键字:文档 查找 结果 XML 两个 处理 | 更新日期: 2023-09-27 18:33:54

我有一些XML文档:

事件.xml:

<?xml version="1.0" encoding="UTF-8"?>
<events>
  <event>
    <id>9</id> 
    <region>3</region> 
    <region>12</region> 
    <region>29</region> 
  </event>
  <event> 
    <id>7</id> 
    <region>1</region>
    <region>12345</region>
  </event>
  <event> 
    <id>3</id> 
    <region>12</region>
    <region>39</region> 
    <region>56</region> 
  </event>
  <event> 
    <id>8</id> 
    <region>8</region> 
    <region>123</region> 
    <region>456</region>
  </event>
  <event> 
    <id>4</id> 
    <region>999</region> 
    <region>888</region> 
    <region>777</region> 
  </event>
</events>

曝光.xml:

<?xml version="1.0" encoding="UTF-8"?>
<companies>
  <company> 
    <id>6</id>
    <region>3</region>
    <region>9</region> 
    <region>8</region>
    <region>11111</region> 
    <region>12</region> 
  </company>
  <company> 
    <id>4</id> 
    <region>3</region> 
    <region>6</region> 
    <region>7</region> 
    <region>12345</region> 
  </company>
  <company> 
    <id>9</id> 
    <region>1</region> 
    <region>2</region> 
    <region>3</region> 
  </company>
</companies>

我需要编写一个程序来处理这两个文件:

对于事件文件中的每个事件,程序应写出 事件编号后跟它受影响的公司集 曝光文件。公司名单应写在 升序公司编号。

给定示例文件,输出应如下所示:

 9 4 6 9 8 6 7 4 9 3 6

处理两个 XML 文档以查找结果

在你的生活中有一点 LINQ。

var eventsDoc = XDocument.Load(@"events.xml");
var exposureDoc = XDocument.Load(@"exposure.xml");
var companies =
   (from c in exposureDoc.Descendants("company")
    let id = (int)c.Element("id")
    orderby id
    select new
    {
        Id = id,
        Regions = new HashSet<int>(
            from r in c.Elements("region")
            select (int)r),
    }).ToList();
var events =
    from e in eventsDoc.Descendants("event")
    let id = (int)e.Element("id")
    orderby id descending
    select new
    {
        Id = id,
        Regions = from r in e.Elements("region")
                  select (int)r,
    };
foreach (var evnt in events)
{
    var affectedCompanies =
        from c in companies
        where c.Regions.Overlaps(evnt.Regions)
        select c.Id;
    if (affectedCompanies.Any())
        Console.WriteLine("{0} {1}", evnt.Id, String.Join(" ", affectedCompanies));
}

如果使用的是 .NET 3.5,则需要稍微更改循环正文中的查询。

var affectedCompanies =
   (from c in companies
    where c.Regions.Overlaps(evnt.Regions)
    select c.Id.ToString()).ToArray();

您可以使用 XInclude 有效地将这两者组合到一个文档中,如下所示:

<?xml version="1.0" ?>
<combination xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="events.xml" />
    <xi:include href="exposure.xml" />
</combination>

然后

  1. 使用 XmlDocument 阅读"组合"文档
  2. 使用 SelectNodes 拉入事件列表 (XPath: '//event/id./')
  3. 使用选择节点拉入每个事件的区域列表
  4. 使用SelectNodes拉入受每个地区影响的公司

有很多关于如何使用 XmlDocument 框架和 XPath 的文档。比如这个问题。