Olen tallentamassa xml tiedostoon eri tiedostojen tietoja. Jossain vaiheessa indeksointi tyssää (tosin kääntäjä ei herjaa mitään) ja kun aikansa tutkiskeli, niin vaikuttaisi että homma tyssää sellaisiin tiedoston nimiin, joissa esiintyy & merkki. On varmaan joitain muitakin, mutta itellä ei tullut vastaan.
Mistähän voisi johtua? xml encode on utf-8 ja esim ääkkösiä sisältävät tiedoston nimet on sekametelisoppaa, mutta menevät xml tiedostoon ihan mukisematta.
foreach (MyFile file in files) { XmlNode fileNode = doc.CreateNode(XmlNodeType.Element, "file", ""); fileNode.InnerXml = String.Format("<name>{0}</name><size>{1}</size>", file.Name, file.Size); filesNode.AppendChild(fileNode); }
Kaikki toimii kivasti, mutta jos tulee sellainen argumentti, joka sisältää & merkin (esim "kaikkea & kivaa.txt") silmukassa saa napattua exception messagen "An error occurred while parsing EntityName. Line 1, position 15"
Kaikki tekstit pitää tietenkin muuttaa XML-muotoon.
merkki | muunnos |
---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
Kaksi viimeistä ovat välttämättömiä vain silloin, kun merkki katkaisisi ennenaikaisesti attribuutin arvon.
public static string EscapeXML(string s) { return s.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("'", "'").Replace("\"", """); }
Tähän on myös eräitä valmiita funktioita, joita voit etsiä netistä.
Jesh, kiitoksia!
Kun kerran osaat nätisti tehdä XmlNoden, miksi ihmeessä haluat osan sisällöstä tehdä merkkijonona? Paljon parempi tapa olisi käyttää nodeja ja antaa järjestelmän pitää huoli siitä, että tiedot ovat varmasti oikein XML:ssä.
Myöskin XDocumentin ja kavereiden kanssa tuo menee vielä kätevämmin koska kutsuja voi ketjuttaa. Ja toki tuosta saa myös onelinerin jos tahtoo:
doc = new XDocument( new XElement("files", (from file in files select new XElement("file", new XElement("name", file.Name), new XElement("size", file.Size) ) ) ) );
Tai jos halutaan vain tallentaa XML-tiedosto eikä käsitellä sitä muistissa, voi käyttää XmlWriteriä.
Ja jos kilkkeet on suoraan merkkijonossa:
string xmlStuff = "<Files><File><Name>Tiedosto.txt</Name><Size>12</Size></File></Files>"; XDocument doc = XDocument.Parse(xmlStuff);
Aihe on jo aika vanha, joten et voi enää vastata siihen.