如何用c#从XML中删除重复的属性

本文关键字:属性 删除 何用 XML | 更新日期: 2023-09-27 18:01:21

我正在解析一些来自第三方提供商的XML文件,不幸的是它并不总是格式良好的XML,因为有时某些元素包含重复的属性。

我无法控制源,我不知道哪些元素可能有重复的属性,也不知道重复的属性名称。

显然,将内容加载到XMLDocument对象中会在重复属性上引发XmlException,因此我认为可以使用XmlReader逐个元素遍历XML元素,并在到达错误元素时处理重复属性。

然而,在我有机会检查元素的属性之前,XmlExceptionreader.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();
}

是否有另一种方法来解析输入和删除重复的属性,而不必使用正则表达式和字符串操作?

如何用c#从XML中删除重复的属性

我找到了一个解决方案,将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

这将使您能够获得所有属性值。