1

我正在为荷兰的游泳运动员建立一个包含比赛、俱乐部、结果和更多信息的数据库。由于我收到的数据发生了一些变化,我遇到了我正在阅读的 XML 文件中重复值的问题。

这是导致问题的 XML 文件的一部分:

<LENEX version="3.0">
  <MEETS>
    <MEET name="Speedowedstrijd 2012 - 2013 deel 1">
      <CLUB name="AZVD" type="CLUB" nation="NED" region="08" code="08-004">
        <OFFICIALS>
          <OFFICIAL nation="NED" gender="M" officialid="2329" lastname="xx">
            <CONTACT email="xx" phone="xx" country="NL" />
          </OFFICIAL>
        </OFFICIALS>
      </CLUB>
      <CLUB name="A.Z.V.D." type="CLUB" nation="NED" region="8" code="08-004">
        <ATHLETES>
          <ATHLETE nation="NED" gender="M" athleteid="2358" license="xx" lastname="xx">
            <RESULTS>
              <RESULT eventid="1167" resultid="2359" swimtime="00:03:09.69">
                <SPLITS>
                  <SPLIT distance="50" swimtime="00:00:40.71"/>
                  <SPLIT distance="100" swimtime="00:01:30.71"/>
                </SPLITS>
              </RESULT>
            </RESULTS>
          </ATHLETE>
        </ATHLETES>
      </CLUB>
    </MEET>
  </MEETS>
</LENEX>

现在读取 xml 文件不是问题,使用 XDocument 我得到所有节点、子节点等。但是,当我将值写入我的数据库时,我在 Club_Meet 表上得到一个 keyconstraint 错误。该表包含俱乐部表和会议表之间的链接,并且每个组合必须是唯一的。由于上面示例中的两个俱乐部都指向我的数据库中的同一个俱乐部(唯一代码 = 08-004,我试图将相同的值写入数据库两次,从而导致错误。

所以我想做的是当我浏览 xml 文件并找到一个俱乐部时:检查这个俱乐部之前是否已经在这个 XML 中找到,如果是,则将子节点挂在第一个俱乐部节点下。此操作的结果应该是(内部):

<LENEX version="3.0">
  <MEETS>
    <MEET name="Speedowedstrijd 2012 - 2013 deel 1">
      <CLUB name="AZVD" type="CLUB" nation="NED" region="08" code="08-004">
        <OFFICIALS>
          <OFFICIAL nation="NED" gender="M" officialid="2329" lastname="xx">
            <CONTACT email="xx" phone="xx" country="NL" />
          </OFFICIAL>
        </OFFICIALS>
        <ATHLETES>
          <ATHLETE nation="NED" gender="M" athleteid="2358" license="xx" lastname="xx">
            <RESULTS>
              <RESULT eventid="1167" resultid="2359" swimtime="00:03:09.69">
                <SPLITS>
                  <SPLIT distance="50" swimtime="00:00:40.71"/>
                  <SPLIT distance="100" swimtime="00:01:30.71"/>
                </SPLITS>
              </RESULT>
            </RESULTS>
          </ATHLETE>
        </ATHLETES>
      </CLUB>
    </MEET>
  </MEETS>
</LENEX>

请注意,第二个俱乐部节点<CLUB name="A.Z.V.D." type="CLUB" nation="NED" region="8" code="08-004">已完全删除,我不需要该节点的任何内容。如何将子节点从一个俱乐部移动到另一个俱乐部并删除空俱乐部?谁能指出我正确的方向?

(希望这一切都有意义....)

4

1 回答 1

1

好的,所以如果您想严格操作 XML 文档,您可以使用我创建的以下扩展方法。

public static class XmlExtensions
{
   public static IEnumerable<XElement> CombineLikeElements(this IEnumerable<XElement> source, Func<XElement, object> groupSelector)
   {
      // used to record the newly combined elements
      List<XElement> priElements = new List<XElement>();

      // group the current xml nodes by the supplied groupSelector, and only
      // select the groups that have more than 1 elements.
      var groups = source.GroupBy(groupSelector).Where(grp => grp.Count() > 1);

      foreach(var grp in groups)
      {
         // get the first (primary) child element and use it as 
         // element that all the other sibling elements get combined with.
         var priElement = grp.First();

         // get all the sibling elements which will be combined
         // with the primary element.  Skipping the primary element.
         var sibElements = grp.Skip(1);

         // add all the sibling element's child nodes to the primary
         // element.
         priElement.Add(sibElements.Select(node => node.Elements()));

         // remove all of the sibling elements
         sibElements.Remove();

         // add the primary element to the return list
         priElements.Add(priElement);
      }

      // return the primary elements incase we want to do some further
      // combining of their descendents
      return priElements;
   }
}

您将按如下方式使用扩展方法:

XDocument xmlDoc = XDocument.Parse(xml);
xmlDoc
   // Combine all of the duplicate CLUB nodes under each MEET node
   .Descendants("MEET").Descendants("CLUB").CombineLikeElements(node => node.Attribute("code").Value);

它会返回您请求的结果。

我有扩展方法返回一个 XElements 列表,如果你想组合它们的子节点,所有东西都被组合成。例如,如果在组合相同的 CLUB 元素后,一个或多个 CLUB 最终具有两个或多个 ATHLETES 或 OFFICIALS 节点,您也可以通过执行以下操作轻松组合它们:

xmlDoc
   // Combine all of the duplicate CLUB nodes under each MEET node
   .Descendants("MEET").Descendants("CLUB").CombineLikeElements(node => node.Attribute("code").Value)
   // Combine all of the duplicate ALTHLETES or OFFICIALS nodes under the newly combined CLUB nodes
   .Elements().CombineLikeElements(node => node.Name);
于 2012-10-13T00:21:24.240 回答