【问题标题】:XElement add node on specific position not working as expectedXElement 在特定位置添加节点未按预期工作
【发布时间】:2016-03-01 02:18:44
【问题描述】:

我有以下 XML 文件:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<JMF SenderID="InkZone-Controller" Version="1.2">
  <Command ID="cmd.00695" Type="Resource">
    <ResourceCmdParams ResourceName="InkZoneProfile" JobID="K_41">
      <InkZoneProfile ID="r0013" Class="Parameter" Locked="False" Status="Available" PartIDKeys="SignatureName SheetName Side Separation" DescriptiveName="Schieberwerte von DI" ZoneWidth="32">
        <InkZoneProfile SignatureName="SIG1">
          <InkZoneProfile Locked="false" SheetName="S1">
            <InkZoneProfile Side="Front">
              <ColorPool Class="Parameter" DescriptiveName="Colors for the job" Status="Available" />
              <Color Name="PANTONE 647 C" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Black" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Yellow" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Magenta" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Cyan" CMYK="1 1 0 0" sRGB="0 0 1" />
            </InkZoneProfile>
            <InkZoneProfile Separation="Cyan" ZoneSettingsX="0  0,006 0" />
            <InkZoneProfile Separation="Magenta" ZoneSettingsX="0 0,031  0" />
            <InkZoneProfile Separation="Yellow" ZoneSettingsX="0 0,021  0" />
            <InkZoneProfile Separation="Black" ZoneSettingsX="0 0,005  0" />
            <InkZoneProfile Separation="PANTONE 647 C" ZoneSettingsX="0,002 0"/>
          </InkZoneProfile>
        </InkZoneProfile>
      </InkZoneProfile>
    </ResourceCmdParams>
  </Command>
</JMF>

我想在&lt;InkZoneProfile Side="Front"&gt; 之后专门添加一个节点。我为此发出以下表达式:

XElement InkZonePath = XmlDoc.Root.Descendants("InkZoneProfile").Where(z => (string)z.Attribute("Side") == "Front").SingleOrDefault();
var InkZoneProfilePosition = InkZonePath.Parent; 
if (InkZoneProfilePosition != null)
                    {
                        InkZoneProfilePosition.Add(new XElement("InkZoneProfile",
                                    new XAttribute("Separation", x.colorname),
                                    new XAttribute("ZoneSettingsX", x.colorvalues)));
                    }

不是在我指定的位置添加节点,而是在 &lt;ColorPool Class&gt; 节点之后添加节点 - 我需要在 &lt;InkZoneProfile Side="Front"&gt; 之后添加节点

我正在寻找的输出示例:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<JMF SenderID="InkZone-Controller" Version="1.2">
  <Command ID="cmd.00695" Type="Resource">
    <ResourceCmdParams ResourceName="InkZoneProfile" JobID="K_41">
      <InkZoneProfile ID="r0013" Class="Parameter" Locked="False" Status="Available" PartIDKeys="SignatureName SheetName Side Separation" DescriptiveName="Schieberwerte von DI" ZoneWidth="32">
        <InkZoneProfile SignatureName="SIG1">
          <InkZoneProfile Locked="false" SheetName="S1">
            <InkZoneProfile Side="Front">
                       <InkZoneProfile Separation="Cyan" ZoneSettingsX="0 0,005 " />
            <InkZoneProfile Separation="Magenta" ZoneSettingsX="0  0" />
            <InkZoneProfile Separation="Yellow" ZoneSettingsX="0 0,021 0" />
            <InkZoneProfile Separation="Black" ZoneSettingsX="0 0,005 " />
            <InkZoneProfile Separation="PANTONE 647 C" ZoneSettingsX="0 0,003 " />
              <ColorPool Class="Parameter" DescriptiveName="Colors for the job" Status="Available" />
              <Color Name="PANTONE 647 C" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Black" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Yellow" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Magenta" CMYK="1 1 0 0" sRGB="0 0 1" />
              <Color Name="Cyan" CMYK="1 1 0 0" sRGB="0 0 1" />
            </InkZoneProfile>
          </InkZoneProfile>
        </InkZoneProfile>
      </InkZoneProfile>
    </ResourceCmdParams>
  </Command>
</JMF>

当我调试代码时,变量,即使在建议的更改之后,var 仍然包含 &lt;ColorPool&gt; 节点。

有没有办法做到这一点?我在网上看到的所有示例以及我从这里得到的帮助都提到了使用 Descendants(CORRECTED: using parent now),因为我想在某些根级别的后代之后添加节点。

提前致谢。

EDIT1:根据 Sakura 的评论更新代码更改 - 结果 XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<JMF SenderID="InkZone-Controller" Version="1.2">
  <Command ID="cmd.00695" Type="Resource">
    <ResourceCmdParams ResourceName="InkZoneProfile" JobID="K_41">
      <InkZoneProfile ID="r0013" Class="Parameter" Locked="False" Status="Available" PartIDKeys="SignatureName SheetName Side Separation" DescriptiveName="Schieberwerte von DI" ZoneWidth="32">
        <InkZoneProfile SignatureName="SIG1">
          <InkZoneProfile Locked="false" SheetName="S1">
            <InkZoneProfile Side="Front">
              <ColorPool Class="Parameter" DescriptiveName="Colors for the job" Status="Available" />
              <Color Name="PANTONE 647 C" CMYK="1 1 0 0" sRGB="0 0 255" />
              <Color Name="Black" CMYK="1 1 0 0" sRGB="0 0 255" />
              <Color Name="Yellow" CMYK="1 1 0 0" sRGB="0 0 255" />
              <Color Name="Magenta" CMYK="1 1 0 0" sRGB="0 0 255" />
              <Color Name="Cyan" CMYK="1 1 0 0" sRGB="0 0 255" />
              <InkZoneProfile Separation="Name" ZoneSettingsX="Value" />
              <InkZoneProfile Separation="Name" ZoneSettingsX="Value" />
              <InkZoneProfile Separation="Name" ZoneSettingsX="Value" />
              <InkZoneProfile Separation="Name" ZoneSettingsX="Value" />
              <InkZoneProfile Separation="Name" ZoneSettingsX="Value" />
            </InkZoneProfile>
          </InkZoneProfile>
        </InkZoneProfile>
      </InkZoneProfile>
    </ResourceCmdParams>
  </Command>
</JMF>

【问题讨论】:

  • 你能发布一个你期望的示例 XML 吗?
  • 检查我对问题所做的更新。
  • 还是不清楚。所以你想要&lt;level6&gt;&lt;level7/&gt;&lt;newlevel/&gt;&lt;/level6&gt; 而不是&lt;level6&gt;&lt;level7&gt;&lt;newlevel/&gt;&lt;/level7&gt;&lt;/level6&gt;
  • 如果能贴两个XML就更清楚了:一个是你拥有的,一个是你想拥有的。
  • 请检查我的编辑。

标签: c# xml linq xelement


【解决方案1】:

你应该删除这一行:

var InkZoneProfilePosition = InkZonePath.Parent;

然后将Add 更改为AddFirst。应该是:

    XElement InkZonePath = XmlDoc.Root.Descendants("InkZoneProfile").Where(z => (string)z.Attribute("Side") == "Front").SingleOrDefault();
    //var InkZoneProfilePosition = InkZonePath.Parent;
    if (InkZonePath != null)
    {
        InkZonePath.AddFirst(new XElement("InkZoneProfile",
                    new XAttribute("Separation", "Name"),
                    new XAttribute("ZoneSettingsX", "Value")));
    }

【讨论】:

  • 这正是我之前所做的,结果是节点被添加到了错误的位置(就像我发布的示例文件一样)。
  • 您想添加一个元素InkZoneProfile 作为&lt;InkZoneProfile Side="Front"&gt; 的子元素,对吧?
  • 您能否将我输入的内容准确复制/粘贴到您的代码中,看看它是否满足您的需求?
  • 好的。将表单 Add 更改为 AddFirst
  • @PabloCosta 好的。一个问题是,如果你有 3 个元素:e1、e1、e3,它将首先插入 e3,然后是 e2、e1。要解决这个问题,你应该先添加e3,然后添加e2,e1
【解决方案2】:

问题是您的查询返回给定名称的Descendants不是该元素本身)。您可以通过阅读.Parent 来获取该元素的父元素。

var firstdescendant = XmlDoc.Root.Descendants("level6")
  .Where(z => (string)z.Attribute("leveltype") == "thislevel").SingleOrDefault();


var level6element = firstdescendant.Parent; // add null check to  firstdescendant (if required)

工作Demo

【讨论】:

  • 这里没有添加 .Parent 的选项 - 说我缺少一些参考。
  • 我的错,我没有复制整个查询。现已更新。
  • 谢谢。请检查我的编辑,也许我添加了有关我的问题的全部信息。
猜你喜欢
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
相关资源
最近更新 更多