如何用c#从XML中删除重复的属性
本文关键字:属性 删除 何用 XML | 更新日期: 2023-09-27 18:01:21
我正在解析一些来自第三方提供商的XML文件,不幸的是它并不总是格式良好的XML,因为有时某些元素包含重复的属性。
我无法控制源,我不知道哪些元素可能有重复的属性,也不知道重复的属性名称。
显然,将内容加载到XMLDocument
对象中会在重复属性上引发XmlException,因此我认为可以使用XmlReader
逐个元素遍历XML元素,并在到达错误元素时处理重复属性。
然而,在我有机会检查元素的属性之前,XmlException
在reader.Read()
上被提出。
下面是一个示例方法来演示这个问题:
public static void ParseTest()
{
const string xmlString =
@"<?xml version='1.0'?>
<!-- This is a sample XML document -->
<Items dupattr=""10"" id=""20"" dupattr=""33"">
<Item>test with a child element <more/> stuff</Item>
</Items>";
var output = new StringBuilder();
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
{
XmlWriterSettings ws = new XmlWriterSettings();
ws.Indent = true;
using (XmlWriter writer = XmlWriter.Create(output, ws))
{
while (reader.Read()) /* Exception throw here when Items element encountered */
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(reader.Name);
if (reader.HasAttributes){ /* CopyNonDuplicateAttributes(); */}
break;
case XmlNodeType.Text:
writer.WriteString(reader.Value);
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
writer.WriteComment(reader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
}
}
}
}
string str = output.ToString();
}
是否有另一种方法来解析输入和删除重复的属性,而不必使用正则表达式和字符串操作?
我找到了一个解决方案,将XML视为HTML文档。然后使用开源的Html敏捷包库,我能够获得有效的XML。
技巧是先用HTML头保存xml。
替换XML声明<?xml version="1.0" encoding="utf-8" ?>
使用如下HTML声明:!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
一旦内容保存到文件中,该方法将返回一个有效的XML文档。
// Requires reference to HtmlAgilityPack
public XmlDocument LoadHtmlAsXml(string url)
{
var web = new HtmlWeb();
var m = new MemoryStream();
var xtw = new XmlTextWriter(m, null);
// Load the content into the writer
web.LoadHtmlAsXml(url, xtw);
// Rewind the memory stream
m.Position = 0;
// Create, fill, and return the xml document
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml((new StreamReader(m)).ReadToEnd());
return xmlDoc;
}
重复的属性节点被自动删除,后面的属性值覆盖前面的属性值。
好的,我想你需要抓住这个错误:
那么你应该能够使用以下方法:
reader.MoveToFirstAttribute();
和
reader.MoveToNextAttribute()
获取以下属性:
reader.Value
reader.Name
这将使您能够获得所有属性值。