I made a webpage using c# asp.net. It has various text fields and dropdown lists and a radio button. Now i want to save the data into an xml file. and i'm not really able to understand on how to go about it.
The various attributes in my page are TEXTBOX: GInfo; LNo; Org; UName; SType; Ver; MeapSupp; MaxUser; MaxMach; MachIP; MachMac; UqID
DROPDOWNLIST: LType
RADIO BUTTON: MeapSupp
I'm new to XML and asp.net and c#. Can you please help me out.
You can use this code - based on XmlTextWriter class
XmlTextWriter textWriter = new XmlTextWriter("yourpath", null);
// Opens the document
textWriter.WriteStartDocument();
textWriter.WriteStartElement("root");
textWriter.WriteAttributeString("xmlns", "x", null, "urn:1");
// Write comments
textWriter.WriteComment("First Comment XmlTextWriter Sample Example");
textWriter.WriteEndElement();
// Ends the document.
textWriter.WriteEndDocument();
// close writer
textWriter.Close();
Link : http://msdn.microsoft.com/fr-fr/library/system.xml.xmltextwriter.aspx
You can also use LINQ To XML
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("This is a test"),
new XElement("root")
);
var root = doc.CreateElement("Test");
....
Link : http://msdn.microsoft.com/en-us/library/bb387098.aspx
Related
I am currently developing a custom pipeline component for an XML document flow, where the root node and the first child of that root node needs to be stripped off, leaving only the second child node left (which is now the new root node).
I'm using XDocument as container class for the XML document. Ive written some code which gets the second child node, and creates a new XML document with that node as the root, thus removing the two undesired nodes from the picture.
XNode secondChild = xDoc.Root.Elements().First().NextNode;
XDocument outputXml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
secondChild);
But when I test this setup in Biztalk, I only get an empty document back as a response. It seems to create an empty XML document which is then returned.
To give an example of what I want to achieve:
I want to go from a structure like this:
<Root>
<FirstChild></FirstChild>
<SecondChild></SecondChild>
</Root>
To a simple structure like this:
<SecondChild></SecondChild>
The full code of the Execute method in the pipeline:
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
var originalStream = pInMsg.BodyPart.GetOriginalDataStream();
XDocument xDoc; //new XML document to return as the message
using (XmlReader reader = XmlReader.Create(originalStream))
{
reader.MoveToContent();
xDoc = XDocument.Load(reader);
}
XNode secondChild = xDoc.Root.Elements().First().NextNode;
XDocument outputXml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
secondChild);
// Returning stream, serializing the XML to byte array
byte[] output = System.Text.Encoding.ASCII.GetBytes(outputXml.ToString());
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(output, 0, output.Length);
memoryStream.Position = 0;
pInMsg.BodyPart.Data = memoryStream; //overwrite the original message with the modified stream
return pInMsg;
}
Looking around on SO I found this answer, which I tried to follow, but as mentioned it produces an empty document. Is there a different option, other than simply creating a new XDocument?
If you develop a regular map to edit the document you can place it in the maps section of the receive port. It's simpler to create, test, and install than a pipeline component.
I'm building an Parts app in order to learn C# and WPF. I trying having trouble adding new parts using XmlWriter. I can create the xml file, but can not figure how to add additional parts. Should I be using something else like XmlDocument? Here is my code behind:
private void btnSave_Click(object sender, RoutedEventArgs e)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create("f:\\MyParts.xml", settings))
{
writer.WriteStartDocument();
writer.WriteStartElement("MyParts");
writer.WriteStartElement("parts");
writer.WriteStartElement("item");
writer.WriteString(txtbxitem.Text);
writer.WriteEndElement();
writer.WriteStartElement("color");
writer.WriteString(txtbxcolor.Text);
writer.WriteEndElement();
writer.WriteStartElement("size");
writer.WriteString(txtbxsize.Text);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
writer.Close();
}
}
This code creates the xml file and a node correctly, but how do I add additional parts? Here is what I am trying to create:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<MyParts>
<parts>
<item>Part1</item>
<color>Red</color>
<size>SM</size>
</parts>
<parts>
<item>Part2</item>
<color>Blue</color>
<size>XXL</size>
</parts>
</MyParts>
Personally I'd suggest using LINQ to XML. It's a much easier API to use than XmlDocument.
But yes, if you want to modify an existing document then typically using an in-memory representation is simpler than using a streaming API. It's possible to do the latter of course, but it's not easy.
Here's an example to create the same XML as you've already got (other than the declaration: any reason you'd want to use Latin-1 instead of something like UTF-8 which can represent the whole of Unicode, btw?)
var doc = new XDocument(
new XElement("MyParts",
new XElement("parts",
new XElement("item", "Part1"),
new XElement("color", "Red"),
new XElement("size", "SM")),
new XElement("parts",
new XElement("item", "Part2"),
new XElement("color", "Blue"),
new XElement("size", "XXL"))));
Then if you wanted to add another part:
doc.Root.Add(
new XElement("parts",
new XElement("item", "Part3"),
new XElement("color", "Green"),
new XElement("size", "L")));
Admittedly I'd expect you'd want to encapsulate the "create a parts element" bit into a method to avoid repeating it all the time... but hopefully you get the picture.
Use a loop, and you'll end up with something like:
var parts = new List<Part>() { ...... parts here ...... };
using (XmlWriter writer = XmlWriter.Create("f:\\MyParts.xml", settings))
{
writer.WriteStartDocument();
writer.WriteStartElement("MyParts");
foreach(var part in parts)
{
writer.WriteStartElement("parts");
writer.WriteStartElement("item");
writer.WriteString(part.Item);
writer.WriteEndElement(); // </item>
writer.WriteStartElement("color");
writer.WriteString(part.Color);
writer.WriteEndElement();
writer.WriteStartElement("size");
writer.WriteString(part.Size);
writer.WriteEndElement(); // </size>
writer.WriteEndElement(); // </parts>
}
writer.WriteEndElement(); // </MyParts>
writer.WriteEndDocument();
writer.Flush();
writer.Close();
}
The general idea is that, for each part in your list of parts, you write the "parts" (should be "part"?) tag and all of its contents, filling item, color and size with data from a Part class, which in its simplest form might be:
class Part
{
public string Item { get; set; }
public Color Color { get; set; }
public string Size { get; set; }
}
The code above does exactly what it looks like: writes an element "MyParts" and then writes a child element "parts" and then a child element "item" with a value of whatever is in your text box.
This smells suspiciously like homework, and is readily Google-able, so I'm only going to give a quick pseudo-answer.
You (may) want to:
Create appropriate class(es) for parts that have the members you want
Create a collection of those items
Update that in-memory collection from your UI
Save the collection using the XML formatting and functionality of your choice (including but not limited to what you are doing above, or LINQ to XML, or XML Serialization, or...)
Have you considered using the out of the box XML Serialization that comes with .NET? You just populate your objects within some collection and then use the XML Serializer to persist to a file. You can then use the DeSerializer to hydrate your objects.
This would allow your to spend more time on your application's UI (WPF), and logic. All you need to do is all the Serializable attribute to your class.
Here's a good example: http://www.jonasjohn.de/snippets/csharp/xmlserializer-example.htm
The biggest benefit is that as you build your data object over time, the serialization/de-serialization will grow with it.
Hope you can help me a bit. I'm trying to write to an XML file, but am struggling to write the method which, well, writes to the XML file. This is the XML file manually written (using Notepad++ etc.):
<software>
<software_entry
name="Adobe Acrobat X Standard"
path="Applications\Acrobat\Acrobat X Standard\AcroStan.msi"
type="msi"
switches="/qn ALLUSERS=1"
/>
<software_entry
name="Adobe Acrobat X Professional"
path="Applications\Acrobat\Acrobat X Pro\AcroPro.msi"
type="msi"
switches="/qn ALLUSERS=1"
/>
</software>
The aim of this part of the application is to write that using a GUI.
In the application, the user chooses the name of the XML file. It is then saved in the temp folder until further in the process when the user is asked where they would like to save it. Upon entering the desired name of the file and clicking Create, the method called "createAndLoadXML" is run. As its name would suggest, it creates and then loads an XML file (to populate a listview control on the form). Code can be seen below.
private void createAndLoadXML()
{
// Method to create XML file based on name entered by user
string tempPath = Path.GetTempPath();
string configFileName = fileNameTextBox.Text;
string configPath = tempPath + configFileName + ".xml";
// Create XDocument
XDocument document = new XDocument(
new XDeclaration("1.0", "utf8", "yes"),
new XComment("This XML file defines the software selections for use with the Software Installer"),
new XComment("XML file generated by Software Installer"),
new XElement("software",
new XElement("software_entry",
new XAttribute("name", ""),
new XAttribute("path", ""),
new XAttribute("type", ""),
new XAttribute("switches", ""))
)
);
document.Save(configPath);
configCreateLabel.Visible = true;
document = XDocument.Load(configPath);
}
Now, further down this form are 4 text boxes for user input, each relating to the attributes created (name, path, type and switches) The idea is the user will write in these text boxes, click an 'Add' button and then the program will write those 4 fields as attributes to this XML file. So far, I have this code, which is horribly incomplete and doesn't even use LINQ to XML.
private void writeToXML()
{
// Method to write lines to XML file based on user input
// Sets string variables
string fileName = softwareNameTextBox.Text;
string filePath = filePathTextBox.Text;
string fileType = installerType.Text.ToString();
string installSwitches = installSwitchesTextBox.Text;
using (XmlWriter xw = XmlWriter.Load(configPath)) //This line is wrong, I know
{
xw.WriteStartElement("software");
xw.WriteElementString("name", fileName);
xw.WriteElementString("path", filePath);
xw.WriteElementString("type", fileType);
xw.WriteElementString("switches", installSwitches);
xw.WriteEndElement();
}
}
Basically, could anyone please help me with the above method which writes to the XML the data the user has entered into the text box controls? I'm not sure how to load the previously created XML document (from my createAndLoadXML method), and how to write within the root element (software) using LINQ to XML.
Try this out. I think this should get you what you want assuming the XML exists beforehand since you are calling createAndLoadXML before this method. I wrote this in NotePad++, so I may have a error or two.
private void writeToXML()
{
// Method to write lines to XML file based on user input
// Sets string variables
string fileName = softwareNameTextBox.Text;
string filePath = filePathTextBox.Text;
string fileType = installerType.Text.ToString();
string installSwitches = installSwitchesTextBox.Text;
string FILE_PATH = "bla.xml";
XDocument xDoc = XDocument.Load(FILE_PATH);
xDoc.Root.Add(new XElement("software_entry",
new XAttribute("name", fileName),
new XAttribute("path", filePath),
new XAttribute("type", fileType),
new XAttribute("switches", installSwitches)
));
xDoc.Save(FILE_PATH);
}
I have an XML in the following format
<Attachment>
<AttachmentName>Top Nav Menu.docx</AttachmentName>
<Subject>Attachment1</Subject>
<Sender>JameelM#orioninc.com</Sender>
</Attachment>
I want to attach another Attachment like above after the attachment close node. Below are the code that i have written for writing xml file
var doc = new XDocument(
new XDeclaration("1.0", "utf-16", "true"),
new XProcessingInstruction("test", "value"),
new XElement("Attachment",new XElement("AttachmentName", attachment.Name),
new XElement("Subject", exchangeEmailInformation.Subject),
new XElement("Sender", exchangeEmailInformation.Sender
)));
doc.Save(ConfigInformation.BackUpPath + FolderId[index]+"\\Attachments"+index+".xml");
Create root node for your attachments:
var doc = new XDocument(
new XDeclaration("1.0", "utf-16", "true"),
new XProcessingInstruction("test", "value"),
new XElement("Attachments",
new XElement("Attachment",
new XElement("AttachmentName", attachment.Name),
new XElement("Subject", exchangeEmailInformation.Subject),
new XElement("Sender", exchangeEmailInformation.Sender)
)));
When you decide to append another attachment, load document and add attachment to root:
doc.Root.Add(new XElement("Attachment",
new XElement("AttachmentName", attachment.Name),
new XElement("Subject", exchangeEmailInformation.Subject),
new XElement("Sender", exchangeEmailInformation.Sender)
));
I would use the XMLSerializer class. There you can handle your XML files just as if they are classes. Just have a look, you will like it :)
Load XML -> Use Classes in Code (modify, delete, add) -> Serialize back into XML
I'm trying to create an XML with multiple root elements. I can't change that because that is the way I'm supposed to send the XML to the server. This is the error I get when I try to run the code:
System.InvalidOperationException: This operation would create an incorrectly structured document.
Is there a way to overwrite this error and have it so that it ignores this?
Alright so let me explain this better:
Here is what I have
XmlDocument doc = new XmlDocument();
doc.LoadXml(_application_data);
Now that creates the XML document and I can add a fake root element to it so that it works. However, I need to get rid of that and convert it into a DocumentElement object.
How would I go about doing that?
Specify Fragment when creating XmlWriter as shown here
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.CloseOutput = false;
// Create the XmlWriter object and write some content.
MemoryStream strm = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(strm, settings))
{
writer.WriteElementString("orderID", "1-456-ab");
writer.WriteElementString("orderID", "2-36-00a");
writer.Flush();
}
If it has multiple root elements, it's not XML. If it resembles XML in other ways, you could place everything under a root element, then when you send the string to the server, you just combine the serialized child elements of this root element, or as #Austin points out, use an inner XML method if available.
just create an XML with single root then get it's content as XML text.
you are talking about XML fragment anyways, since good xml has only one root.
this is sample to help you started:
var xml = new XmlDocument();
var root = xml.CreateElement("root");
root.AppendChild(xml.CreateElement("a"));
root.AppendChild(xml.CreateElement("b"));
Console.WriteLine(root.InnerXml); // outputs "<a /><b />"