-1

我有一些 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
4

2 回答 2

3

在你的生活中拥有一点 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();
于 2012-05-12T16:18:25.900 回答
1

您可以使用 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. 使用 SelectNodes 拉入每个事件的区域列表
  4. 使用 SelectNodes 拉入受每个区域影响的公司

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

于 2012-05-12T16:00:46.940 回答