2012-05-12 54 views
-1

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

我需要編寫一個程序來處理這兩個文件:

對於事件文件中的每個事件,pro克應寫出 事件編號,後面跟着它在 曝光文件中影響的公司集合。公司名單應寫在 遞增的公司編號。

給出的樣本文件,輸出應該是這樣的:

 
9 4 6 9 

8 6 

7 4 9 

3 6 

回答

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(); 
+0

既然我沒有更好的事情做......這個人是免費的。 –

+0

感謝這個傑夫...一個新手linq的位,但它看起來相當高效...只是得到輸出的參數錯誤...錯誤最好的重載方法匹配的'string.Join (string,string [])'有一些無效參數 錯誤參數'2':無法從'System.Collections.Generic.IEnumerable '轉換爲'string []'有什麼想法?謝謝 – omarlittle

+0

看到我的答案的最後一部分,這聽起來像你使用.NET 3.5,所以你需要做一些調整。 –

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的文檔。例如,這question