如何搜索 xml 节点值,然后在 c# 中为该元素创建新属性
Posted
技术标签:
【中文标题】如何搜索 xml 节点值,然后在 c# 中为该元素创建新属性【英文标题】:how to search for a xml node value, then create new attribute for that element in c# 【发布时间】:2021-01-02 17:26:26 【问题描述】:我正在使用 c# .net 4.6 xpath 搜索具有 id 值的节点,并在找到时为父元素创建一个新属性。我有一个此类 id 值的列表,我需要对其进行迭代并创建属性以生成新的 xml 文档。我尝试了以下但不起作用。 XPathNavigator.MoveTo 方法似乎将源导航器替换为移动到的元素,从而丢失了所有其他内容。这不是实现这一目标的正确方法吗?可以请教吗?
参见下面的代码 sn-p:
publicationDoc.LoadXml(publicationXPathNav.OuterXml);
XPathNavigator publicationNav = publicationDoc.CreateNavigator();
foreach (IListBlobItem item in contentDirectory.ListBlobs())
var blob = (CloudBlob)item;
string contentId = blob.Name;
XPathNavigator contentRefNav = publicationNav.SelectSingleNode($@"//releaseItem/contentRef[id = "'" + contentId + "'"]/..");
if (contentRefNav != null)
publicationNav.MoveTo(contentRefNav); // here publicationNav gets replaced by contentRefNav
publicationNav.CreateAttribute("", "fileName", "", contentFileName);
// once finished with the foreach I was hoping to be able to save the publicationNav.OuterXml to a new file with the newly added attributes.
这里是一个小的缩减示例源 xml 数据:
<publicationsRoot>
<publication>
<urn>iso:pub:std:FDIS:74824</urn>
<releaseItems>
<releaseItem>
<languageNeutral>false</languageNeutral>
<type>STANDARD</type>
<contentRef>
<id>92764155</id>
</contentRef>
</releaseItem>
<releaseItem>
<languageNeutral>false</languageNeutral>
<type>STANDARD</type>
<contentRef>
<id>92802320</id>
</contentRef>
</releaseItem>
<releaseItem>
<languageNeutral>false</languageNeutral>
<type>STANDARD</type>
<contentRef>
<id>92801989</id>
</contentRef>
</releaseItem>
<releaseItems>
</publication>
</publicationsRoot>
【问题讨论】:
请编辑您的帖子,并添加所需的输出 XML。 考虑在System.Xml.Linq
中使用现代API
【参考方案1】:
用字典试试 xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication167
class Program
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, XElement> dict = doc.Descendants("id")
.GroupBy(x => (string)x, y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
string id = "92764155";
string filename = "filename";
if (dict.ContainsKey(id))
dict[id].SetAttributeValue("filename", filename);
【讨论】:
【参考方案2】:我设法通过不使用 XPathNavigator 并仅依赖 XMLDocuent 来解决此问题。 XPathNavigator 似乎更适合相对路径,而我的要求是搜索特定节点并更新 xml 文档。
publicationDoc.LoadXml(publicationXPathNav.OuterXml);
foreach (IListBlobItem item in contentDirectory.ListBlobs())
var blob = (CloudBlob)item;
string contentId = blob.Name;
XmlNode contentRefNode = publicationDoc.SelectSingleNode($@"//releaseItem/contentRef[id = "'" + contentId + "'"]/..");
if (contentRefNode != null)
XmlAttribute fileName = publicationDoc.CreateAttribute("fileName");
fileName.Value = contentFileName + contentFileExt;
contentRefNode.Attributes.SetNamedItem(fileName);
// once finished with the foreach I was hoping to be able to save the publicationNav.OuterXml to a new file with the newly added attributes.
感谢您的所有回答。我一定会接受这些。
【讨论】:
以上是关于如何搜索 xml 节点值,然后在 c# 中为该元素创建新属性的主要内容,如果未能解决你的问题,请参考以下文章