nodo modificar manipular leer especifico crear atributos archivo agregar c# xml recursion attributes treeview

modificar - Recursión, analizando el archivo xml con atributos en treeview c#



leer y modificar xml c# (2)

Debe mover el bucle a través de atributos fuera del bucle a través de nodos secundarios:

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(); }

Actualizar

Si desea filtrar los atributos del espacio de nombres, puede agregar métodos de extensión :

public static class XmlNodeExtensions { public static bool IsDefaultNamespaceDeclaration(this XmlAttribute attr) { if (attr == null) return false; if (attr.NamespaceURI != "http://www.w3.org/2000/xmlns/") return false; return attr.Name == "xmlns"; } 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:"); } }

Luego, XmlAttribute para omitir instancias XmlAttribute no XmlAttribute . También puede establecer explícitamente el texto de todos los nodos de tipo XmlElement para que sean datos de nombre + atributo, no solo aquellos elementos con elementos OuterXml , utilizando OuterXml solo para nodos de texto:

private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode) { if (inXmlNode is XmlElement) { // An element. Display element name + attribute names & values. foreach (var att in inXmlNode.Attributes.Cast<XmlAttribute>().Where(a => !a.IsNamespaceDeclaration())) { inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value; } // Add children foreach (XmlNode xNode in inXmlNode.ChildNodes) { var tNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(xNode.Name))]; AddNode(xNode, tNode); } } else { // Not an element. Character data, comment, etc. Display all text. inTreeNode.Text = (inXmlNode.OuterXml).Trim(); } treeView1.ExpandAll(); }

Si realmente desea filtrar solo las definiciones de espacio de nombres predeterminadas pero dejar otras, puede hacer lo siguiente:

// An element. Display element name + attribute names & values. foreach (var att in inXmlNode.Attributes.Cast<XmlAttribute>().Where(a => !a.IsDefaultNamespaceDeclaration())) { inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value; }

Por cierto, no recomiendo hacer esto, ya que lo siguiente realmente significa lo mismo, es decir, un elemento con el nombre local DataConfiguration en el espacio de nombres http://somenamespace :

<ss:DataConfiguration xmlns:ss="http://somenamespace"/> <DataConfiguration xmlns="http://somenamespace"/>

Su árbol mostrará el espacio de nombres para el primer elemento pero no para el segundo.

Actualización 2

Para incluir la XmlDeclaration en el árbol, cambie el bucle de nivel superior para que sea:

treeView1.Nodes.Clear(); foreach (XmlNode xNode in dom.ChildNodes) { var tNode = treeView1.Nodes[treeView1.Nodes.Add(new TreeNode(xNode.Name))]; AddNode(xNode, tNode); }

Actualización 3

Coloque el bucle para incluir el bucle DisplayTreeView en DisplayTreeView :

private void DisplayTreeView(string pathname) { try { // SECTION 1. Create a DOM Document and load the XML data into it. XmlDocument dom = new XmlDocument(); dom.Load(pathname); // SECTION 2. Initialize the TreeView control. treeView1.Nodes.Clear(); // SECTION 3. Populate the TreeView with the XML nodes. foreach (XmlNode xNode in dom.ChildNodes) { var tNode = treeView1.Nodes[treeView1.Nodes.Add(new TreeNode(xNode.Name))]; AddNode(xNode, tNode); } } catch (XmlException xmlEx) { MessageBox.Show(xmlEx.Message); } catch (Exception ex) { MessageBox.Show(ex.Message); } }

Actualmente estoy trabajando en un proyecto donde una aplicación tomará archivos XML y los mostrará en una vista de árbol en C #. Estoy usando Visual Studio 10 para escribir este código.

No puedo limitar el número de veces que se muestran los atributos. Utilicé un bucle foreach para recorrer cada uno de los atributos que tiene y mostrarlo, pero muestra los atributos una vez para cada nodo secundario que tiene debajo del nodo. ¿Cómo puedo modificar este código para mostrar solo los atributos una vez?

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Xml; namespace xmlToTreeview { public partial class Form1 : Form { string samplePath = Application.StartupPath + @"//sample.xml"; public Form1() { InitializeComponent(); DisplayTreeView(samplePath); } private void DisplayTreeView(string pathname) { try { // SECTION 1. Create a DOM Document and load the XML data into it. XmlDocument dom = new XmlDocument(); dom.Load(pathname); // SECTION 2. Initialize the TreeView control. treeView1.Nodes.Clear(); treeView1.Nodes.Add(new TreeNode(dom.DocumentElement.Name)); TreeNode tNode = new TreeNode(); tNode = treeView1.Nodes[0]; // SECTION 3. Populate the TreeView with the DOM nodes. AddNode(dom.DocumentElement, tNode); } catch (XmlException xmlEx) { MessageBox.Show(xmlEx.Message); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode) { XmlNode xNode; TreeNode tNode; XmlNodeList nodeList; int i; // Loop through the XML nodes until the leaf is reached. // Add the nodes to the TreeView during the looping process. if (inXmlNode.HasChildNodes) { nodeList = inXmlNode.ChildNodes; for (i = 0; i <= nodeList.Count - 1; i++) { xNode = inXmlNode.ChildNodes[i]; inTreeNode.Nodes.Add(new TreeNode(xNode.Name)); tNode = inTreeNode.Nodes[i]; //Check if the XmlNode has attributes if (inXmlNode.Attributes.Count != 0) { foreach (XmlAttribute att in inXmlNode.Attributes) { inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value; } } 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(); } } }

Y aquí hay un ejemplo de mi xml

<?xml version="1.0" encoding="utf-8"?> <DataConfiguration xmln="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" id="ccc" principal="ccc" nioarc="ccc" nap="ccc" group="ccc"> </webfg> <nhood port="1234"/> <ServerNames> <!-- insert comment --> <!-- insert comment --> <!-- insert comment --> <ServerName>myname</ServerName> <ServerName>yourname</ServerName> </ServerNames> <!-- insert comment --> <Implementations> <Implementation> <Name>yourname</Name> <Type>typeme</Type> <Assembly>visionme</Assembly> <Path>ohno</Path> </Implementation> </Implementations>--> <cfgman port="ccc" /> <webservice provider="ccc" /> <webservice provider="ccc" /> <webservice provider="ccc" /> <parameters> <useeventpush value="ccc"/> </parameters> <webservice provider="ccc" /> <pollingFrequency value="1000"/> </DataGroup> </DataPool> <DataGroup Id="ccc " UserCanSelectHost="ccc" > <DataGroup Id="ccc " UserCanSelectHost="ccc" > <HostId>idk</HostId> <DataSources> <empty/> </DataSources> </DataGroup> <DataGroup Id="ccc " UserCanSelectHost="ccc" > <HostId>idk</HostId> <DataSources> <empty/> </DataSources> </DataGroup> <DataGroup Id="default" UserCanSelectHost="true" > <HostId>idk</HostId> </DataGroup> </DataGroup> </DataPools> </DataConfiguration>


Prueba un algoritmo recursivo simple

static void Main(string[] args) { string input = "<a>" + "<b>" + "<c>val1</c>" + "<d>val2</d>" + "</b>" + "<e>val3</e>" + "<f>val4</f>" + "</a>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(input); RecursiveRead(doc.DocumentElement); } static string RecursiveRead(XmlNode node) { List<string> children = new List<string>(); bool done = false; if (node.HasChildNodes) { foreach (XmlNode child in node) { children.Add(RecursiveRead(child)); } Console.WriteLine("table : {0}; children : {1}", node.Name, string.Join(",", children.ToArray())); //string cmd = "INSERT INTO " + second + " (" + first + ") VALUES (''" + xml.Value + "'')"; //SqlCommand command = new SqlCommand(cmd, conn); //command.ExecuteNonQuery(); } else { return node.Value; } return node.Name; }