使用 c~ 有条件地将 XElement 添加到新的 XElement

Conditionally adding a XElement to a new XElement using c~

我正在尝试使用 XElement 向现有 XML 数据文件添加新内容。

大部分情况下它工作正常,但我需要更改它。这是我目前所拥有的:

xdoc.Root.Add(
    new XElement("W" + record.Date.ToString("yyyyMMdd"),
        new XElement("Chairman", historyItem.Chairman),
        new XElement("AuxCounsellor1", historyItem.AuxCounsellor1),
        new XElement("AuxCounsellor2", historyItem.AuxCounsellor2),
        new XElement("VideoConferenceHost", string.Empty),
        new XElement("VideoConferenceCohost", string.Empty),
        new XElement("PrayerOpen", historyItem.PrayerOpen),
        new XElement("PrayerClose", historyItem.PrayerClose),
        new XElement("CBSConductor", historyItem.CBSConductor),
        new XElement("CBSReader", historyItem.CBSReader),
        new XElement("ReviewQuestion", string.Empty),
        new XElement("Items",
            new XAttribute("ItemCount", historyItem.TalkItems.Count),
            new XElement("Item",
                new XElement("Name", historyItem.TalkItems[0].Name),
                new XElement("Theme", historyItem.TalkItems[0].Theme),
                new XElement("Method", historyItem.TalkItems[0].Method)),
            new XElement("Item",
                new XElement("Name", historyItem.TalkItems[1].Name),
                new XElement("Theme", historyItem.TalkItems[1].Theme),
                new XElement("Method", historyItem.TalkItems[1].Method)),
            new XElement("Item",
                new XElement("Name", historyItem.TalkItems[2].Name),
                new XElement("Theme", historyItem.TalkItems[2].Theme),
                new XElement("Method", historyItem.TalkItems[2].Method)),
            new XElement("Item",
                new XElement("Name", historyItem.TalkItems[3].Name),
                new XElement("Theme", historyItem.TalkItems[3].Theme),
                new XElement("Method", historyItem.TalkItems[3].Method)),
            new XElement("Item",
                new XElement("Name", historyItem.TalkItems[4].Name),
                new XElement("Theme", historyItem.TalkItems[4].Theme),
                new XElement("Method", historyItem.TalkItems[4].Method)),
            new XElement("Item",
                new XElement("Name", historyItem.TalkItems[5].Name),
                new XElement("Theme", historyItem.TalkItems[5].Theme),
                 new XElement("Method", historyItem.TalkItems[5].Method)))));

它创建这样的条目:

  <W20220404>
    <Chairman></Chairman>
    <AuxCounsellor1></AuxCounsellor1>
    <AuxCounsellor2></AuxCounsellor2>
    <VideoConferenceHost></VideoConferenceHost>
    <VideoConferenceCohost></VideoConferenceCohost>
    <PrayerOpen></PrayerOpen>
    <PrayerClose></PrayerClose>
    <CBSConductor></CBSConductor>
    <CBSReader></CBSReader>
    <ReviewQuestion></ReviewQuestion>
    <Items ItemCount="6">
      <Item>
        <Name></Name>
        <Theme>“Come essere un vero amico”</Theme>
        <Method>Talk</Method>
      </Item>
      <Item>
        <Name></Name>
        <Theme>Spiritual Gems</Theme>
        <Method>Question and Answers</Method>
      </Item>
      <Item>
        <Name></Name>
        <Theme>Prepare This Month's Presentations</Theme>
        <Method>Discussion with Video</Method>
      </Item>
      <Item>
        <Name></Name>
        <Theme>“Chi sono i tuoi amici online?”</Theme>
        <Method>Discussion with Video</Method>
      </Item>
      <Item>
        <Name></Name>
        <Theme>Diamo il benvenuto agli ospiti</Theme>
        <Method>Discussion with Video</Method>
      </Item>
      <Item>
        <Name></Name>
        <Theme></Theme>
        <Method>Talk</Method>
      </Item>
    </Items>
  </W20220404>

现在,我想在 W20220404 节点中添加另一个项目,就在 Items 列表之后。例如:

<Teaching>
    <Name Class="0">Brother 9</Name>
    <Name Class="1">Brother 1</Name>
    <Name Class="2">Brother 3</Name>
</Teaching>

但是:

  1. 如果historyItem.Classes >= 1我只想添加第一个Name
  2. 如果historyItem.Classes >= 2我只想添加第二个Name
  3. 如果historyItem.Classes == 3我只想添加第三个Name

我不知道如何附加它。最初我尝试扩展我的代码:

new XElement("Teaching",
    new XElement("Name",
        new XAttribute("Class", 0),
        new XText(historyItem.Teaching[0])),
    new XElement("Name",
        new XAttribute("Class", 1),
        new XText(historyItem.Teaching[1])),
    new XElement("Name",
        new XAttribute("Class", 2),
        new XText(historyItem.Teaching[2])))));

但它没有考虑逻辑要求。使用指示的规则添加此节点的明智方法是什么?

总结一下:

Create the Teaching node
if Teaching is not null
    if historyItem.Classes >= 1
         Add the first Name / attribute
    if historyItem.Classes >= 2
         Add the second Name / attribute
    if historyItem.Classes == 3
         Add the third Name / attribute

因此,如果 Teaching 元素为空,我希望 XML 中有一个空的 Teaching 元素。

有道理吗?

您可以利用 null 节点被忽略的事实,因此在不满足条件时传递 null 的条件。 这是基本思想:

new XElement("Teaching",
    historyItem.Classes >= 1 ? new XElement("Name",
        new XAttribute("Class", 0),
        new XText(historyItem.Teaching[0])) : null,

阅读评论后,您似乎甚至不需要条件,可以执行以下操作:

historyItem.Teaching != null ? new XElement("Teaching",
    new XElement("Name",
        new XAttribute("Class", historyItem.Classes - 1),
        new XText(historyItem.Teaching[historyItem.Classes - 1]))
        ), null));

我想我会添加这个作为最初答案的替代方案,后者的处理方式略有不同。使用一个大链并考虑 Teaching 节点的逻辑要求的替代方法:

XElement historyWeek = new XElement("W" + record.Date.ToString("yyyyMMdd"));

if(historyItem.Meeting)
{
    historyWeek.Add(new XElement("Chairman", historyItem.Chairman),
        new XElement("AuxCounsellor1", historyItem.AuxCounsellor1),
        new XElement("AuxCounsellor2", historyItem.AuxCounsellor2),
        new XElement("VideoConferenceHost", string.Empty),
        new XElement("VideoConferenceCohost", string.Empty),
        new XElement("PrayerOpen", historyItem.PrayerOpen),
        new XElement("PrayerClose", historyItem.PrayerClose),
        new XElement("CBSConductor", historyItem.CBSConductor),
        new XElement("CBSReader", historyItem.CBSReader),
        new XElement("ReviewQuestion", string.Empty));

    XElement historyTalkItems = new XElement("Items",
        new XAttribute("ItemCount", historyItem.TalkItems.Count));
    foreach (var talkItem in historyItem.TalkItems)
    {
        historyTalkItems.Add(new XElement("Item",
                    new XElement("Name", talkItem.Name),
                    new XElement("Theme", talkItem.Theme),
                    new XElement("Method", talkItem.Method)));
    }
    historyWeek.Add(historyTalkItems);

    XElement historyTeaching = new XElement("Teaching");
    if(historyItem.Teaching.Any())
    {
        for (int iClass = 0; iClass < historyItem.Classes; iClass++)
        {
            historyTeaching.Add(new XElement("Name",
                new XAttribute("Class", iClass),
                new XText(historyItem.Teaching[iClass])));
        }
    }
    historyWeek.Add(historyTeaching);
}
xdoc.Root.Add(historyWeek);