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

时间:2012-05-12 15:21:12

标签: c# xml

我有一些XML文档:

events.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>

exposure.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

2 个答案:

答案 0 :(得分: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();

答案 1 :(得分: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. 读入“合并”文档
  3. 使用SelectNodes拉入事件列表(XPath:`// event / id ./')
  4. 使用SelectNodes拉入每个事件的区域列表
  5. 使用SelectNodes吸引受每个区域影响的公司
  6. 有很多关于如何使用XmlDocument框架和XPath的文档。例如,这question