在特定节点/元素后插入XML片段

4

我想向XML文档的最后一个元素添加XML片段,但我遇到了问题,即我收到的错误是:

“引用节点不是此节点的子项”。

因此,我的现有XML文档如下所示:

<MAP>
  <LAYER name ="My first Layer">
    <DATASET name="foo dataset" />
    <SYMBOLOGY> 
      <SYMBOL colour="red" />
    </SYMBOLOGY>    
  </LAYER>
  <LAYER name="My second Layer">
     <DATASET name="bar dataset" /> 
     <SYMBOLOGY> 
       <SYMBOL colour="blue" />
     </SYMBOLOGY>    
  </LAYER>    
</MAP>

我想要插入到最后一个LAYER元素后面的XML片段是:
<LAYER name="My third Layer">
     <DATASET name="whatever dataset" /> 
     <SYMBOLOGY> 
       <SYMBOL colour="yellow" />
     </SYMBOLOGY>    
</LAYER> 

我使用的代码是:

我正在使用以下代码:

XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment();
xmlDocFrag.InnerXml = inputXML; //which is basically the third layer example - see above.

XmlElement rootElement = xmlDocument.DocumentElement;
XmlNode lastLayerNode = rootElement.SelectSingleNode(@"//LAYER[last()]");

rootElement.InsertAfter(xmlDocFrag, lastLayerNode); //error raised here.

非常感谢您的提问。我认为我的XPath查询似乎是正确的,它选择了正确的最后一层,只是由于某种奇怪的原因它不会在它之后插入。 更新/解决方案 - 如何使用XPATH实现此操作 最终在XPath中找到了解决方法 - 请参见下面的代码,我认为问题在于一开始没有选择正确的父节点,选择最后一个LAYER然后尝试在该节点上执行InsertAfter()是错误的。更好的方法是选择上一级即MAP,然后执行AppendChild()。请参考以下内容:
XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment();
xmlDocFrag.InnerXml = inputXML;

XmlElement mapElement = (XmlElement)xmlDocument.SelectSingleNode(@"//MAP[last()]");
mapElement.AppendChild(xmlDocFrag);

感谢所有的回复和帮助 :)
3个回答

5
考虑到您需要与2.0框架一起使用,这里提供另一种解决方案:
string xml = "<map><layer>1</layer><layer>2</layer></map>";
string addMe = "<layer>3</layer>";

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);

XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment();
xmlDocFrag.InnerXml = addMe;

XmlElement rootElement = xmlDocument.DocumentElement;
rootElement.AppendChild(xmlDocFrag);

这将导致:
<map><layer>1</layer><layer>2</layer><layer>3</layer></map>

@Vidar 我避免使用XPath是因为个人偏好。 - arcain
这确实可以工作,但是MAP元素有一些其他子元素,比如<PROPERTIES>,它会在此元素之后附加新层,看起来有点丑。有什么解决方法吗? - Vidar
@Vidar如果您可以修改文档格式,也许您想要添加一个“层”元素来包含“层”元素? - arcain
实际上已经解决了,我想我在 XML 方面做错了什么,一遍又一遍地重新测试代码。现在它可以工作了,图层很好地嵌套在 MAP 元素中。仍然很烦人为什么 Xpath 不能正常工作。 - Vidar

0

我曾经遇到过类似的问题,我使用了ImportNode方法来解决它。

这里有一个小例子,展示如何使用该方法将来自不同XML(存储在字符串中)的节点添加到您的示例中,并放置在XML树中所需的节点位置。

string xmlstring =@"<tag>.....</tag>"; // holds xml tree to be appended
       XmlDocument xml2 = new XmlDocument();
        xml2.Load(@"path_of_main_xml");

        XmlDocument xml1 = new XmlDocument();
        xml1.Load(new StringReader(xmlString));

        // get the node you want to import which in this icase is string
        XmlNode elem = xml1.DocumentElement;
 // use importNode to import it
        XmlNode impnode = xml2.ImportNode(elem,true);
 // get the node list of all node of particular tag name
        XmlNodeList eNode = xml2.GetElementsByTagName("tag_name_of_parent");
        eNode[0].AppendChild(impnode); // append new node
// write back the updates to same file
        XmlWriter writer = XmlWriter.Create(@"path_of_main_xml");
        xml2.Save(writer); 

0

情况看起来很不错,但我首先会尝试避免使用xpath选择最后一个节点,而是直接使用以下方法:

rootElement.InsertAfter(xmlDocFrag, rootElement.LastChild);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接