I'm trying to store Some values to an xml file.I've already created an Xml file and trying to overwrite data. The code is given..
/*storepassword.cs *//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
public class StorePassword
{
public StorePassword()
{
}
public void store(NewPassword nps)
{
XmlDocument XmlDoc = new XmlDocument();
//XmlDoc.Load(#"Password.xml");
XmlDoc.LoadXml("Password.xml");
XmlNode root = XmlDoc.DocumentElement;
XmlNode myNode1 = root.SelectSingleNode("UserName");
XmlNode myNode2 = root.SelectSingleNode("PassWord");
myNode1.Value = "sjn";
myNode2.Value = "sjn123";
XmlDoc.Save(#"Password.xml");
}
}
//NewPassword.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class NewPassword
{
public NewPassword()
{
}
public string username{ get; set; }
public string Password{ get; set; }
}
on button click..
NewPassword nps = new NewPassword();
nps.username = TxtUser.Text;
nps.Password = TxtNewPassword.Text;
StorePassword sp=new StorePassword();
sp.store(nps);
The existing Xml file contains the following..
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<UserName>abc</UserName>
<PassWord>123</PassWord>
</ROOT>
But it's not working..
Data at the root level is invalid. Line 1, position 1
this error occures..
Ichanged the code as XmlDoc.Load(#"Password.xml");
now error changed to
Root element is missing.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Xml.XmlException: Root element is missing.
why this happens?
Try using XML Serialization:
public static partial class ObjectXMLSerializer<T> where T : class
{
private static void SaveToDocumentFormat(T serializableObject, System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder)
{
using (TextWriter textWriter = CreateTextWriter(isolatedStorageFolder, path))
{
XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);
//Cuong: set name space to null
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
xmlSerializer.Serialize(textWriter, serializableObject, ns);
}
}
public static void Save(T serializableObject, string path)
{
SaveToDocumentFormat(serializableObject, null, path, null);
}
}
When you load your Xml you need to use Server.MapPath . XmlDoc.LoadXml(Server.MapPath("Password.xml"));
delete
<?xml version="1.0" encoding="utf-8"?>
from
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<UserName>abc</UserName>
<PassWord>123</PassWord>
</ROOT>
I do not know why it works but we do that all the time in our code. And yes you should be using XmlDocument.Load not XmlDocument.LoadXml
Related
How to make my XML Document to looks like the following:
<?xml version="1.0" encoding="utf-8" ?>
<Diff>
<Delete file="file0.ext"/>
<Create file="file1.ext"/>
<Create dir="dir1"/>
<Create dir="dir1\dir2"/>
<Create file="dir1\dir2\file2.ext"/>
</Diff>
If i start from this :
static class DirectoryComparer
{
public static XmlDocument Compare(string oldPath, string newPath)
{
XmlDocument xml = new XmlDocument();
// TODO: Needs to fill "xml" here
return xml;
}
}
The XmlDocument instance has a CreateElement method that allows you to create elements for your XmlDocument instance. The newly created Element (that is an XmlNode) can then be added to the Document Object Model by calling AppendChild. The Element has a SetAttribute methode to add attributes to the element.
Combining all that an implementation to get exactly your example XML might loo like this:
static class DirectoryComparer
{
public static XmlDocument Compare(string oldPath, string newPath)
{
XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateXmlDeclaration("1.0", "utf-8", null));
XmlElement diff = xml.CreateElement("Diff");
xml.AppendChild(diff);
diff.AppendChild(DeleteFile(xml,"file0.ext"));
diff.AppendChild(CreateFile(xml,"file1.ext"));
diff.AppendChild(CreateDir(xml,"dir1"));
diff.AppendChild(CreateDir(xml,#"dir1\dir2"));
diff.AppendChild(CreateFile(xml,#"dir1\dir2\file2.ext"));
return xml;
}
private static XmlElement DeleteFile(XmlDocument xml, string file)
{
XmlElement delete = xml.CreateElement("Delete");
delete.SetAttribute("file", file);
return delete;
}
private static XmlElement CreateFile(XmlDocument xml, string file)
{
return CreateFileOrDir(xml, "file", file);
}
private static XmlElement CreateDir(XmlDocument xml, string dir)
{
return CreateFileOrDir(xml, "dir", dir);
}
private static XmlElement CreateFileOrDir(XmlDocument xml, string attribute,string value)
{
XmlElement create = xml.CreateElement("Create");
create.SetAttribute(attribute, value);
return create;
}
}
And when run from LinqPad the output looks like this:
Using Xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication40
{
class Program
{
const string FILENAME = #"c:\temp\test.csv";
static void Main(string[] args)
{
string ident = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Diff></Diff>";
XDocument doc = XDocument.Parse(ident);
XElement root = doc.Root;
root.Add(new object[] {
new XElement("Delete", new XAttribute("file", "file0.ext")),
new XElement("Create", new XAttribute("file", "file1.ext")),
new XElement("Create", new XAttribute("dir", "dir1")),
new XElement("Create", new XAttribute("dir", "dir2")),
new XElement("Create", new XAttribute("file", #"dir1\dir2\file2.ext"))
});
doc.Save(FILENAME);
}
}
}
I have this replicate scenario my XML document below:
<?xml version="1.0" encoding="utf-8"?>
<Home>
<Kitchen>
<Pantry>
<Ingredients>
<Name>Tomato</Name>
<ID>1</Price_ID>
<Name>Tomato</Name>
<Income>Sales</Income> // replace the <Income> element with its value <Sales>
<Cost>Materials</Cost>
<Price>100</Price> // the value for new <Sales> element shall be this <Price> value
</Ingredients>
//.. and thousands more sets of ingredients
</Pantry>
</Kitchen>
</Home>
//.. and thousands more sets of ingredients
And I want to restructure it in the following manner:
<?xml version="1.0" encoding="utf-8"?>
<Home>
<Kitchen>
<Pantry>
<Ingredients>
<Name>Tomato</Name>
<ID>1</ID>
<Name>Tomato</Name>
<Sales>100</Sales> // the <Income> was replaced by its value and the value was taken from the <Price> element that was deleted also
<Cost>Materials</Cost>
</Ingredients>
//.. and thousands more sets of ingredients
</Pantry>
</Kitchen>
</Home>
I'm still trying to figure out how I'm going to do this. I will appreciate any help here.
Using Xml Ling :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication37
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> ingredients = doc.Descendants("Ingredients").ToList();
foreach (XElement ingredient in ingredients)
{
XElement xIncome = ingredient.Element("Income");
XElement xPrice = ingredient.Element("Price");
xIncome.ReplaceWith(new XElement("Sales", (string)xPrice));
xPrice.Remove();
}
}
}
}
Firstly create a Class for the new Model
public class NewIngredients
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Sales { get; set; }
public string Cost{ get; set; }
}
Presuming the Xml Document is in a file called Kitchen.xml
XElement Kitchen = XElement.Load(#"Kitchen.xml");
then use Linq to Xml to create your new model from the old something like this (Note probably need to check for nulls etc)
var newIngredients = Kitchen.Descendants("Ingredients").Select(x => new NewIngredients
{
Id = int.Parse(x.Element("ID").Value),
Name = x.Element("Name").Value,
Sales = decimal.Parse(x.Element("Price").Value)
Cost = x.Element("Cost").Value
});
Convert back to xml if needed
var serializer = new XmlSerializer(newIngredients.First().GetType());
serializer.Serialize(Console.Out, newIngredients.First()); //Printed to console but could move to file if needed
I am loading my data from XML using C# this way:
XmlDocument xmlDoc = new XmlDocument();
TextAsset xmlFile = Resources.Load("levels/" + levelID) as TextAsset;
xmlDoc.LoadXml(xmlFile.text);
XmlNodeList levelsList = xmlDoc.GetElementsByTagName("level");
foreach (XmlNode levelInfo in levelsList)
{
XmlNodeList childNodes = levelInfo.ChildNodes;
foreach (XmlNode value in childNodes)
{
switch (value.Name)
{
case "info":
//levelWidth = getInt(value, 0);
//levelHeight = getInt(value, 1);
break;
}
}
}
And heres XML I am loading:
<?xml version="1.0" encoding="utf-8" ?>
<level>
<info w="1000" h="500"/>
</level>
It works just fine, I am now trying to find best way to load child nodes, inside my level node with multiple points nodes inside
<?xml version="1.0" encoding="utf-8" ?>
<level>
<info w="1000" h="500"/>
<ground>
<point val1="val1" val2="val2"/>
</ground>
</level>
I will be grateful for some guidance how to move in the right direction, thank you.
Using XML Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
"<level>" +
"<info w=\"1000\" h=\"500\"/>" +
"</level>";
XDocument doc = XDocument.Parse(xml);
XElement level = (XElement)doc.FirstNode;
level.Add("ground", new object[] {
new XElement("point", new XAttribute[] {
new XAttribute("val1", "val1"),
new XAttribute("val2", "val2")
})
});
}
}
}
If you need read all points, you can use
var nodeList = Xmldocument.SelectNodes("level/info/ground/point");
SelectNodes return a list of nodes.
I would go for a slidely different way and use a data object. Then you don't have to analyse xml, you just code your data class:
[Serializable()]
public class CLevel
{
public string Info { get; set; }
}
[Serializable()]
public class CDatafile
{
public List<CLevel> LevelList { get; set; }
public CDatafile()
{
LevelList = new List<CLevel>();
}
}
public class DataManager
{
private string FileName = "Data.xml";
public CDatafile Datafile { get; set; }
public DataManager()
{
Datafile = new CDatafile();
}
// Load file
public void LoadFile()
{
if (System.IO.File.Exists(FileName))
{
System.IO.StreamReader srReader = System.IO.File.OpenText(FileName);
Type tType = Datafile.GetType();
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
object oData = xsSerializer.Deserialize(srReader);
Datafile = (CDatafile)oData;
srReader.Close();
}
}
// Save file
public void SaveFile()
{
System.IO.StreamWriter swWriter = System.IO.File.CreateText(FileName);
Type tType = Datafile.GetType();
if (tType.IsSerializable)
{
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
xsSerializer.Serialize(swWriter, Datafile);
swWriter.Close();
}
}
Then you can use it to create, save and load the file like this:
DataManager dataMng = new DataManager();
// Create some data
CLevel level = new CLevel();
level.Info = "Testlevel";
dataMng.Datafile.LevelList.Add(level);
// Save to file
dataMng.SaveFile();
// Load from file
dataMng.LoadFile();
So you can do everything in code checked by the compiler. Makes life a lot easier, or what do you think?
I am working on a XNA gaming project and keep receiving the following error:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll
Additional information: There is an error in XML document (2, 2).
This is my Xml code:
<?xml version="1.0" encoding="utf-8" ?>
<SplashScreen>
<Path>\SplashScreen\Game.png</Path>
</SplashScreen>
And this is my C# Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
namespace WindowsGame3
{
public class Manager<T>
{
public Type Type;
public T Load(string Path)
{
T instance;
using (TextReader reader = new StreamReader(Path))
{
XmlSerializer xml = new XmlSerializer(Type);
instance = (T)xml.Deserialize(reader);
}
return instance;
}
public void save(string Path, object obj)
{
using (TextWriter writer = new StreamWriter(Path))
{
XmlSerializer xml = new XmlSerializer(Type);
xml.Serialize(writer, obj);
}
}
}
}
Here's the code that uses the above Manager class:
public void LoadContent(ContentManager Content)
{
this.Content = new ContentManager(Content.ServiceProvider, "Content");
GameScreenManager = new Manager<GameScreen>();
GameScreenManager.Type = currentScreen.Type;
currentScreen = GameScreenManager.Load("SplashScreen.xml");
currentScreen.LoadContent();
}
Did you check to see if the type T that you are calling the Load method on matches proper casing of the root element name SplashScreen ?
I could get this XML file from C# class with XmlSerializer.
<?xml version="1.0" encoding="utf-8"?>
<Component xmlns:spirit="b" xmlns:chrec="a" MovieName="0" BlocksNotCovered="0">
<ClassInfoList>
<chrec:string>hello</chrec:string>
<chrec:string>world</chrec:string>
</ClassInfoList>
<moduleName />
<world>
<x>10</x>
<y>20</y>
</world>
</Component>
How can I add prefix namespaces for chrec and spriti? For example, how can I get this XML file?
<?xml version="1.0" encoding="utf-8"?>
<spirit:Component xmlns:spirit="b" xmlns:chrec="a" MovieName="0" BlocksNotCovered="0">
<spirit:ClassInfoList>
<chrec:string>hello</chrec:string>
<chrec:string>world</chrec:string>
</spirit:ClassInfoList>
<spirit:moduleName />
<chrec:world>
<chrec:x>10</chrec:x>
<chrec:y>20</chrec:y>
</chrec:world>
</spirit:Component>
This is the C# code.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Linq;
namespace Coverage
{
public class Hello
{
public int x;
public int y;
public Hello()
{
x = 10;
y = 20;
}
}
public class Component {
[XmlAttribute("MovieName")]
public int MovieName;
[XmlAttribute("BlocksNotCovered")]
public int BlocksNotCovered;
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces ns;
public List<string> ClassInfoList;
public string moduleName;
public Hello world;
public Component()
{
ClassInfoList = new List<string>() {"hello", "world"};
MovieName = 0;
BlocksNotCovered = 0;
moduleName = "";
world = new Hello();
}
}
class Cov2xml
{
static void Main(string[] args)
{
string xmlFileName = "perf.xml";
Component report = new Component();
TextWriter writeFileStream = new StreamWriter(xmlFileName);
report.ns = new XmlSerializerNamespaces();
report.ns.Add("chrec","a");
report.ns.Add("spirit","b");
var ser = new XmlSerializer(typeof(Component));
ser.Serialize(writeFileStream, report, report.ns);
writeFileStream.Close();
}
}
}
Thanks to the link from competent_tech, I could figure out the way to do it.
How to set the prefix namespace?
You can use XmlRootAttribute, the important thing is that the names space is the namespace, not the namespace name. In the example, it should be "b" not "chrec".
[XmlRootAttribute("Component", Namespace="http://namespace", IsNullable = false)]
public class Component {
How to set the prefix namespace for a specific element?
You can use XmlElement just before the variable.
[XmlElement("xyz", Namespace="http://www.namespace", IsNullable = false)]
int x;
And you'll get this.
<?xml version="1.0" encoding="utf-8"?>
<chrec:Component xmlns:spirit="http:..." MovieName="0" BlocksNotCovered="0" xmlns:chrec="...">
<chrec:ClassInfoList>
<chrec:string>hello</chrec:string>
<chrec:string>world</chrec:string>
</chrec:ClassInfoList>
<chrec:moduleName />
<chrec:world>
<spirit:xyz>10</spirit:xyz>
<chrec:y>20</chrec:y>
</chrec:world>
</chrec:Component>