【问题标题】:Adding or Updating XML Node添加或更新 XML 节点
【发布时间】:2015-11-11 20:19:32
【问题描述】:

如果节点已经存在,我需要添加几个子节点或更新节点。正如您从下面的小示例中看到的那样,我有一个带有子节点的节点,而另一个没有。假设我有一个来自 SQL 表的定义,我想将值添加到节点。

XML

<workbook>
<datasources>
    <column datatype='real' name='[CONTRACT_PAYMENT_AMT]' role='measure' type='quantitative'>
        <desc>
          <formatted-text>
            <run>The amount being paid on the contract.</run>
          </formatted-text>
        </desc>
    </column>
    <column datatype='real' name='[CONTRACT_PAYMENT_DATE]' role='measure' type='quantitative'>
    </column>
</datasources>

这是我只需要获取 name 属性的代码。 Columns 是可能包含数据类型、名称、角色和类型的类。

IEnumerable<string> names = from Columns in XDocument.Load(path).Descendants("column")                                        
                                    select Columns.Attribute("name").Value;

        foreach (string name in names)
        {

        }

这是该方法的开始。

我无法考虑如何存储值并更新 XML 文档,或者只是查看每个节点并在它通过文档时进行更新。有什么想法吗?

编辑 - 向当前运行节点添加新值但不添加新值的新代码..与定义。

var document = XDocument.Load(path);
            var elements = (from column in document.Descendants("column")
                            select new
                                {
                                    AttributeName = column.Attribute("name").Value,
                                    Run = column.Descendants("run").FirstOrDefault() ?? new XElement("run")
                                }).ToList();

            foreach (var item in elements)
            {
                if (item.Run == null) continue;
                else 
                {
                    item.Run.Value = GetVariable(item.AttributeName);
                                     // Getvariable is the method that returns the definition
                }
            }

            document.Save(path);

【问题讨论】:

  • 你想更新什么?属性还是整个节点?
  • @CodeNotFound 基于名称属性,我想查询该名称的值表,然后使用我的表中的定义添加 desc 子节点。定义将位于 <.run>
  • 属性名称上是否可以有多个列元素具有相同的值?
  • @CodeNotFound 我不相信有多个相同的属性名称。
  • 我有一个方法可以查询我的表,您只需将节点值添加到参数中,它将以字符串形式返回关联的定义。

标签: c# xml tableau-api


【解决方案1】:

你可以点下面的逻辑:

var document = XDocument.Load(path);
var elements = (from column in document.Descendants("column")
               select new
               {
                    AttributeName = column.Attribute("name").Value,
                    Parent = column,
                    Run = column.Descendants("run").FirstOrDefault()
               }).ToList();

foreach(var item in elements)
{
     XElement run;
     if (item.Run == null)
     {
          run = new XElement("run");
          item.Parent.Add(
              new XElement("desc", 
                  new XElement("formatted-text", 
                      run
                  )
              )
          );
      }
      else
      {
           run = item.Run;
      }

      if(item.AttributeName == "BlaBlaOne")
      {
           run.Value = "Your definition here";
      }
 }

 document.Save(path);

【讨论】:

  • 完美,这非常简单,但我无法理解语法。标记为答案。
  • 它正在更新 Run 节点,但我无法让它在 Column 节点下添加一个。是不是因为我们没有完整的节点堆栈?我在顶部添加了适合您提出的代码的新信息。
  • 看起来 if 中的 item.Parent.Add 不起作用。在.Item 之后我没有Parent 选项。我在想也许 item.Run.AddBeforeSelf?想法?
  • 我在 linq 查询中添加了 Parent 属性。确保您在 Select 查询中添加了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
相关资源
最近更新 更多