使用 XElement 删除节点时出现奇怪问题
Strange issue while using XElement to remove a node
所以我有以下代码,我在其中使用 XDocument
库来解析我的 XML
并对所需的 XML 执行相关操作。
现在,在删除特定块下的节点时,我观察到它删除了块的结束标记。请参考此处的工作程序来演示此行为:
您会看到我正在尝试删除 hl1
元素下的 lang
标签。它成功删除了 lang
标签,但也删除了 </hl1>
结束标签。
为什么会发生这种行为?
这里的另一个问题是如何在 hl1
元素下添加一个具有新值的 lang
节点并删除多个节点?
代码:
using System;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Text;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var doc = XDocument.Parse(@"<?xml version='1.0' encoding='utf-8'?>
<!--<!DOCTYPE nitf SYSTEM 'nitf-3-4.dtd'>-->
<nitf>
<head>
</head>
<body>
<body.head>
<hedline>
<hl1 id='Headline1' class='1' style='Headline1' MainHead='true'>
<lang class='3' style='Headline1' font='Patrika15' fontStyle='Bold' size='18'>राजस्थान:</lang>
<lang class='3' style='Headline1' font='Patrika15' fontStyle='Bold' size='18'>ऑनलाइनऑफलाइन रजिस्ट्रेशन</lang>
</hl1>
<hl2 id='Headline2' class='1' style='Headline2' MainHead='false'>
<lang class='3' style='Headline2' font='Patrika15' fontStyle='Bold' size='30'>53.15 लाख बच्चों को टीके लगाने के लिए 3456 केन्द्र</lang>
</hl2>
<hl2 id='Headline2' class='1' style='Headline2' MainHead='false'>
<lang class='3' style='Headline2' font='Patrika15' fontStyle='Bold' size='30'>53.15 लाख बच्चों को टीके लगाने के लिए 3456 केन्द्र 12</lang>
</hl2>
</hedline>
<summary></summary>
<quotes>
<quote></quote>
</quotes>
</body.head>
<body.content id='Bodytext'>
</body.content>
</body>
</nitf>");
var element = doc.XPathSelectElement("//hedline");
int hl1=0;
foreach (XNode node in element.Nodes())
{
if(node.ToString().Contains("<hl1"))
{
hl1++;
string h1text=string.Empty;
var x = node.XPathSelectElements("lang");
int count = x.Count();
var mylist = x.ToList();
Console.WriteLine(doc);
for(int i=0; i<count;i++)
{
mylist[i].Remove();
}
Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
Console.WriteLine(doc);
}
}
}
}
实际上,当您删除 lang
标签时,hl1
标签会转换为“Self-Closing
”标签。这意味着 hl1
标签是一个空元素。不管怎样,请尝试使用下面的代码删除 hl1
标签的 children 并创建新标签。
public static void Main()
{
var doc = XDocument.Parse(@"Your XML content");
//var element = doc.XPathSelectElement("//hedline");
//int hl1 = 0;
foreach (XElement xElement in doc.Descendants("hl1"))
{
#region remove lang tags
var langElements = xElement.XPathSelectElements("lang");
langElements.Remove();
#endregion
#region create new element in this 'hl1' tag
xElement.Add(CreateElement());
#endregion
}
Console.WriteLine(doc);
}
private static XElement CreateElement()
{
XElement xe = new XElement("lang");
xe.SetAttributeValue("class", 3);
xe.SetAttributeValue("style", "Headline1");
xe.SetAttributeValue("font", "Patrika15");
xe.SetAttributeValue("fontStyle", "Bold");
xe.SetAttributeValue("size", "18");
xe.Value = "My Value";
return xe;
}
所以我有以下代码,我在其中使用 XDocument
库来解析我的 XML
并对所需的 XML 执行相关操作。
现在,在删除特定块下的节点时,我观察到它删除了块的结束标记。请参考此处的工作程序来演示此行为:
您会看到我正在尝试删除 hl1
元素下的 lang
标签。它成功删除了 lang
标签,但也删除了 </hl1>
结束标签。
为什么会发生这种行为?
这里的另一个问题是如何在 hl1
元素下添加一个具有新值的 lang
节点并删除多个节点?
代码:
using System;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Text;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var doc = XDocument.Parse(@"<?xml version='1.0' encoding='utf-8'?>
<!--<!DOCTYPE nitf SYSTEM 'nitf-3-4.dtd'>-->
<nitf>
<head>
</head>
<body>
<body.head>
<hedline>
<hl1 id='Headline1' class='1' style='Headline1' MainHead='true'>
<lang class='3' style='Headline1' font='Patrika15' fontStyle='Bold' size='18'>राजस्थान:</lang>
<lang class='3' style='Headline1' font='Patrika15' fontStyle='Bold' size='18'>ऑनलाइनऑफलाइन रजिस्ट्रेशन</lang>
</hl1>
<hl2 id='Headline2' class='1' style='Headline2' MainHead='false'>
<lang class='3' style='Headline2' font='Patrika15' fontStyle='Bold' size='30'>53.15 लाख बच्चों को टीके लगाने के लिए 3456 केन्द्र</lang>
</hl2>
<hl2 id='Headline2' class='1' style='Headline2' MainHead='false'>
<lang class='3' style='Headline2' font='Patrika15' fontStyle='Bold' size='30'>53.15 लाख बच्चों को टीके लगाने के लिए 3456 केन्द्र 12</lang>
</hl2>
</hedline>
<summary></summary>
<quotes>
<quote></quote>
</quotes>
</body.head>
<body.content id='Bodytext'>
</body.content>
</body>
</nitf>");
var element = doc.XPathSelectElement("//hedline");
int hl1=0;
foreach (XNode node in element.Nodes())
{
if(node.ToString().Contains("<hl1"))
{
hl1++;
string h1text=string.Empty;
var x = node.XPathSelectElements("lang");
int count = x.Count();
var mylist = x.ToList();
Console.WriteLine(doc);
for(int i=0; i<count;i++)
{
mylist[i].Remove();
}
Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
Console.WriteLine(doc);
}
}
}
}
实际上,当您删除 lang
标签时,hl1
标签会转换为“Self-Closing
”标签。这意味着 hl1
标签是一个空元素。不管怎样,请尝试使用下面的代码删除 hl1
标签的 children 并创建新标签。
public static void Main()
{
var doc = XDocument.Parse(@"Your XML content");
//var element = doc.XPathSelectElement("//hedline");
//int hl1 = 0;
foreach (XElement xElement in doc.Descendants("hl1"))
{
#region remove lang tags
var langElements = xElement.XPathSelectElements("lang");
langElements.Remove();
#endregion
#region create new element in this 'hl1' tag
xElement.Add(CreateElement());
#endregion
}
Console.WriteLine(doc);
}
private static XElement CreateElement()
{
XElement xe = new XElement("lang");
xe.SetAttributeValue("class", 3);
xe.SetAttributeValue("style", "Headline1");
xe.SetAttributeValue("font", "Patrika15");
xe.SetAttributeValue("fontStyle", "Bold");
xe.SetAttributeValue("size", "18");
xe.Value = "My Value";
return xe;
}