31. august 2004 - 13:57
Der er
13 kommentarer og 1 løsning
merge / sammensætte XML
Hej Jeg har et par xml dokumenter (XmlDocument) som jeg gerne vil smelte sammen til 1. Hvis f.eks. dokumenterne ser sådan her ud <root> <menu> <menuitem id="1" /> </menu> </root og <root> <menu> <menuitem id="2" /> </menu> </root> så vi jeg gerne have et dokument der ser sådan her ud: <root> <menu> <menuitem id="1" /> <menuitem id="2" /> </menu> </root> Er der en smart måde at gøre det på med C#? - Kasper
Annonceindlæg fra GlobalConnect
31. august 2004 - 14:24
#1
Ganske almindelig XML klasser må da kunne bruges: lave nyt tomt XmlDocument lave root og menu elements åben alle filer og for hver load fil ind i XmlDocument læs alle menuitem tags for hver hver tilføj dem til nyt dokument udskriv nye dokument til fil.
31. august 2004 - 14:30
#2
ok... how???
31. august 2004 - 14:35
#3
Lidt kode framenter: using System.Xml; ... XmlDocument newdoc = new XmlDocument(); XmlElement root = newdoc.CreateElement("root"); newdoc.AppendChild(root) XmlElement menu = newdoc.CreateElement("menu"); root.AppendChild(menu) ... XmlDocument olddoc = new XmlDocument(); olddoc.Load(filnavn); XmlNodeList elements = doc.GetElementsByTagName("menuitem"); foreach(XmlNode element in elements) { XmlElement menuitem = newdoc.CreateElement("menuitem"); menuitem.AppendChild(newdoc.CreateTextNode(element.FirstChild.Value)); menuitem.SetAttribute("id", element.GetAttribute("id")); menu.AppendChild(menuitem) } ... doc.Save("noget.xml");
31. august 2004 - 14:36
#4
Det er bare tastet ind så der er muligvis lidt taste fejl.
31. august 2004 - 15:03
#5
her antager du så en statisk struktur, hvor du ved at alle elementer hedder "menuitem" og at du kender dybten. Det er mig der ikke har udtrykt mig ordentligt. Der kan være op til 8 niveauer i dybden af xml dokumenterne, og jeg aner ikke hvad de enkelte elementer hedder (og dem er der typisk 100-1000 af). Den løsning du foreslår minder om hvad jeg selv kunne tænke på, men det jeg har brug for er noget mere dynamisk. Derfor havde jeg håbet på at der fandtes en metode der selv kan tage hvert element fra det ene dokument og sætte dem ind i det andet.
01. september 2004 - 13:25
#6
Du kan godt erstatte GetElementsByTagName og forech løkken med noget som finder alt dynamisk. Men normalt plejer XML at være lidt mere struktureret.
04. september 2004 - 11:10
#7
Struktuereret: using System; using System.Xml; class MainClass { public static void Main(string[] args) { string[] files = { @"C:\fil1.xml", @"C:\fil2.xml" }; XmlDocument newdoc = new XmlDocument(); XmlElement root = newdoc.CreateElement("root"); newdoc.AppendChild(root); XmlElement menu = newdoc.CreateElement("menu"); root.AppendChild(menu); for(int i = 0; i < files.Length; i++) { XmlDocument olddoc = new XmlDocument(); olddoc.Load(files[i]); XmlNodeList elements = olddoc.GetElementsByTagName("menuitem"); foreach(XmlNode element in elements) { XmlElement menuitem = newdoc.CreateElement("menuitem"); menuitem.SetAttribute("id", ((XmlElement)element).GetAttribute("id")); menu.AppendChild(menuitem); } } newdoc.Save(@"C:\allfiles.xml"); } } Ustruktuereret: using System; using System.Xml; class MainClass { private static void process(XmlNode oldnode, XmlNode newnode) { XmlNodeList childs = oldnode.ChildNodes; foreach(XmlNode child in childs) { switch(child.NodeType) { case XmlNodeType.Element: XmlElement elm = newnode.OwnerDocument.CreateElement(child.Name); foreach(XmlAttribute an in child.Attributes) { elm.SetAttribute(an.Name, an.Value); } newnode.AppendChild(elm); process(child, elm); break; case XmlNodeType.Attribute: XmlAttribute attr = newnode.OwnerDocument.CreateAttribute(child.Name, child.Value); newnode.AppendChild(attr); break; case XmlNodeType.Text: XmlText txt = newnode.OwnerDocument.CreateTextNode(child.Value); newnode.AppendChild(txt); break; } } } public static void Main(string[] args) { string[] files = { @"C:\fil1.xml", @"C:\fil2.xml" }; XmlDocument newdoc = new XmlDocument(); XmlElement root = newdoc.CreateElement("root"); newdoc.AppendChild(root); for(int i = 0; i < files.Length; i++) { XmlDocument olddoc = new XmlDocument(); olddoc.Load(files[i]); process(olddoc.DocumentElement, newdoc.DocumentElement); } newdoc.Save(@"C:\allfiles.xml"); newdoc.Save(Console.Out); } }
06. september 2004 - 12:35
#8
Det kunne måske også være sjovt at se på metoden ImportNode
06. september 2004 - 12:48
#9
Ja faktisk - den ville spare en masse create.
06. september 2004 - 13:12
#10
Man kan vel egentlig også bare snyde lidt: [code] string filenameImport1 = "my first xml"; string filenameImport2 = "my second xml"; string filenameMerged = "my merged file"; XmlTextReader xmlreader1 = new XmlTextReader(filenameImport1); XmlTextReader xmlreader2 = new XmlTextReader(filenameImport2); DataSet ds = new DataSet(); ds.ReadXml(xmlreader1); DataSet ds2 = new DataSet(); ds2.ReadXml(xmlreader2); ds.Merge(ds2); ds.WriteXml(filenameMerged); [/code]
06. september 2004 - 13:14
#11
Men gælder jo kun for samme xml-struktur :-)
11. september 2004 - 21:12
#12
iluka> Er du kommet videre ?
18. august 2010 - 13:53
#13
accepteret
18. august 2010 - 16:51
#14
du skal saette flueben og klikke accepter
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.