首页 >后端开发 >C++ >将带有属性的 XML 解析到 C# TreeView 中时如何防止重复属性显示?

将带有属性的 XML 解析到 C# TreeView 中时如何防止重复属性显示?

Susan Sarandon
Susan Sarandon原创
2025-01-27 11:46:12295浏览

How to Prevent Duplicate Attribute Display When Parsing XML with Attributes into a C# TreeView?

递归:将带有属性的 XML 文件解析为 C 中的 TreeView

问题:

将带有属性的 XML 文件解析为 C# 结果中的树视图在为其拥有的每个子节点多次显示的属性中。如何修改代码才能保证属性只显示一次?

XML 文件示例:

<?xml version="1.0" encoding="utf-8"?>
<DataConfiguration xmlns="abcefg12345" xmlns:xsi="12345abcefg" xsi:schemaLocation="12345abcefg12345abcefg">
  <Hosts>
    <Sites>
        <Site Name="ss">
            <Host Id="aa">
                <Address Host="www.www.com"></Address>
            </Host>
            <Host Id="ee">
                <Address Host="www.www.com"></Address>
            </Host>
            <Host Id="dd">
                <Address Host="www.www.com"></Address>
            </Host> 
            <Host Id="pp">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com/" />
            </Host>
            <Host Id="ss">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
            </Host> 
            <Host Id="561">
                <Address Host="www.www.com"></Address>
            </Host> 
        </Site>
        <Site Name="hihi">
            <Host Id="cc">
                <Address Host="www.www.com"></Address>
            </Host>
            <Host Id="sdD">
                <Address Host="www.www.com"></Address>
            </Host>
            <Host Id="8uj">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" /> 
            </Host>
            <Host Id="222">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />               
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
            </Host>             
        </Site>     
    </Sites>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
            </Host>         
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com" />
            </Host>

</Hosts>
<DataPools>
    <DataPool Id="sss" default="sure">
        <DataGroup Id="sss" Parent="aaa" UserCanSelectHost="sure">
            <HostId Parent="hhhh">I'm breaking here</HostId>
            <DataSources>
                <empty/>
            </DataSources>
        </DataGroup>
        <DataGroup Id="ccc" UserCanSelectHost="whynot">
            <HostId>God I'm breaking here again, i hope you can fix me</HostId>
            <DataSources>
                <empty/>
            </DataSources>
        </DataGroup>
        <DataGroup Id="sss" UserCanSelectHost="yessure">
            <HostId>cry face</HostId>
                <webfg displaygroup="sss" provider="sss">

解决方案:

只显示节点的属性一次,将通过属性的循环移出通过子节点的循环。

private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
    // Loop through the XML nodes until the leaf is reached.
    // Add the nodes to the TreeView during the looping process.
    if (inXmlNode.HasChildNodes)
    {
        //Check if the XmlNode has attributes
        foreach (XmlAttribute att in inXmlNode.Attributes)
        {
            inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value;
        }

        var nodeList = inXmlNode.ChildNodes;
        for (int i = 0; i < nodeList.Count; i++)
        {
            var xNode = inXmlNode.ChildNodes[i];
            var tNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(xNode.Name))];
            AddNode(xNode, tNode);
        }
    }
    else
    {
        // Here you need to pull the data from the XmlNode based on the
        // type of node, whether attribute values are required, and so forth.
        inTreeNode.Text = (inXmlNode.OuterXml).Trim();
    }
    treeView1.ExpandAll();
}

其他增强功能:

过滤命名空间属性:

如果要删除命名空间属性的显示,请使用以下扩展方法:

public static class XmlNodeExtensions
{
    public static bool IsNamespaceDeclaration(this XmlAttribute attr)
    {
        if (attr == null)
            return false;
        if (attr.NamespaceURI != "http://www.w3.org/2000/xmlns/")
            return false;
        return attr.Name == "xmlns" || attr.Name.StartsWith("xmlns:");
    }
}

并使用它来跳过不需要的 XmlAttribute 实例:

foreach (var att in inXmlNode.Attributes.Cast<XmlAttribute>().Where(a => !a.IsNamespaceDeclaration()))
{
    inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value;
}

显示所有节点上的属性和元素文本:

要确保所有节点显示其元素名称和属性数据,而不仅仅是具有子节点的节点,请仅对文本节点使用 OuterXml:

private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
    if (inXmlNode is XmlElement)
    {

以上是将带有属性的 XML 解析到 C# TreeView 中时如何防止重复属性显示?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn