Recently, I have been working with a document using two namespaces. I have been able to create multiple XElements that use the different namespaces, such as has been answered here:
How to load and add elements in an XML tree
The problem, is I need to combine the two dc and opf namespaces in the same element and I cannot figure out how to do that. I use this code to create an XML element:
//open the opf file as an LINQ XML document.
XDocument opfDoc = XDocument.Load(opfFile);
//create the xmlnamespaces required for the <metadata> section of the opf file.
var dc = (XNamespace)"http://purl.org/dc/elements/1.1/";
var opf = (XNamespace)"http://www.idpf.org/2007/opf";
//**add book metadata
meta.Add(new XElement(dc + "creator", bookCreators[0].bookCreator));
The output looks like this:
<dc:creator>Author Name</dc:creator>
What I need to do is to add one or more additional attributes that use another namespace, so the code outputs this:
<dc:creator opf:file-as="Name, Author">Author Name</dc:creator>
I tried writing this code...
meta.Add(new XElement(dc + "creator",
new XmlAttribute(opf + "file-as", bookCreators[0].bookCreatorFileAs),
bookCreators[0].bookCreator));
... But I keep receiving this error message:
xattribute does not contain a constructor that takes two arguments
Can you recommend an approach to fix this problem?
Thanks.
As Henk pointed out, I was using XMLAttribute instead of XAttribute. Once I did this, I got what I needed. Here is the code that works:
meta.Add(new XElement(dc + "creator",
new XAttribute(opf+ "role", "aut"),
new XAttribute(opf+ "file-as",bookCreators[0].bookCreatorFileAs),
bookCreators[0].bookCreator));
Related
I am creating a somewhat complex XML file and I need to include the "ns0" prefix to each XmlElement.
Here are the opening lines of code:
var asnFile = new XmlDocument();
var dec = asnFile.CreateXmlDeclaration("1.0", "UTF-8",null);
asnFile.AppendChild(dec);
var advancedShippingNoticesNode = asnFile.CreateElement("AdvancedShippingNotices");
var advancedShippingNoticesNodeAttr = asnFile.CreateAttribute("xmlns");
advancedShippingNoticesNodeAttr.Value = "http://www.testschema.com/schema/AdvancedShippingNotices.xsd";
advancedShippingNoticesNode.Attributes.Append(advancedShippingNoticesNodeAttr);
asnFile.AppendChild(advancedShippingNoticesNode);
var asnIdNode = asnFile.CreateElement("ASNID");
asnIdNode.InnerText = "TestASN";
advancedShippingNoticesNode.AppendChild(asnIdNode);
I have tried adding a prefix in the following way but the prefix never shows up when opening the saved XML file.
advancedShippingNoticesNode.Prefix = "ns0";
I read here that I'm not able to add a prefix, but since I am creating the XmlDocument on the fly and not loading it from an existing file, I feel like this doesn't apply to my case.
I did try the sample solution in the question/answer linked above, but this XmlDocument has so much nesting that it's hard for me to translate that solution into a working solution for myself. I also feel like that is far too complex just to add a prefix.
Is there a simple way to add a prefix to a new XmlDocument?
I am trying to deserialize a file, none of the other solutions are working for me.
This is the code. I get the error on the 'customerList' line
using (StreamReader customerStreamReader =
new StreamReader(#"C:\...\ShoppingApplication\bin\Debug\Customer.xml"))
{
customerList = (List<Customer>)customerSerializer.Deserialize(customerStreamReader);
}
Look into using XDocument instead for it will be more robust in reporting errors, though the 0,0 location is a common one. Avoid using streams because they are so, .Net 2.
Here is an example:
var doc = XDocument.Load(#"C:\...\ShoppingApplication\bin\Debug\Customer.xml");
Console.WriteLine(doc);
Then extract what is needed from the actual nodes.
For anybody coming here from google:
If you do not want to use XDocument, then you must make sure that your .xml is NOT empty. Once I added something, I was able to deserialize it just fine. Hope this helps!
In my Windows Phone 8 C#/XAML .NET 4.5 Project, I'm trying to create an XDocument with similar structure:
<element1>
<subelement1>
</subelement1>
<subelement2>
...etc...
</subelement2>
</element1>
<element2>
<subelement1>
</subelement1>
<subelement2>
...etc...
</subelement2>
</element2>
The method creating the document looks like (simplified for the question purposes):
... createXML()
{
XDocument doc = new XDocument();
XElement elem1 = new XElement("element1");
elem1.Add(new XElement("subelement1"));
XElement elem2 = new XElement("element2");
doc.Add(elem1);
doc.Add(elem2);
}
But I keep getting InvalidOperationException saying that it would create a invalid document structure.
I know why - it would cause the document to have multiple "root nodes" - but I effectively need it that way.
This structure is needed for webservice done by third party, which recieves the document as a string.
So the question is "How to achieve this structure? Should I use some other XObject instead?"
(I know that probably the most simple solution would be to use collection of XElements...just askin' if there is another way out of curiosity)
The structure that you specified at the top of the post is illegal, because valid XML documents must have a single root element; your document has two elements at the top level, which is not allowed.
You can solve this problem by adding a root element at creation time, and then discarding it when reading the document;
document = new XDocument(new XElement("root", elem1, elem2));
I'm kind of new to XML files in C# ASP.NET. I have a XML in the below format:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Installation>
<ServerIP>192.168.20.110</ServerIP>
<DB_Name>USTCKT1</DB_Name>
<Username>jorame</Username>
<Password>Cru$%e20</Password>
<Table_PreFix>TCK</Table_PreFix>
</Installation>
I need to change the values within each element. For example, when an user clicks I should be able to replace 192.168.20.110 with 192.168.1.12.
How can I accomplish this? Any help will be really appreciated.
You should look at using the methods in the XDocument class. http://msdn.microsoft.com/en-us/library/bb301598.aspx
Specifically look at the methods: Load(string) - to load an XML file, Element() - to access a specific element and Save(string) - to save the XML document. The page on Element() has some sample code which can help.
http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx
You can do something like this using the XDocument class:
XDocument doc = XDocument.Load(file.xml);
doc.Element("Installation").Element("ServerIP").Value = "192.168.1.12";
//Update the rest of the elements
doc.Save(file.xml);
More Details
If you run into namespace issues when selecting your elements you will need to include the xml namespace in the XElement selectors eg doc.Element(namspace + "Installation")
In general, you can do it in the following steps:
Create a new XmlDocument object and load the content. The content might be a file or string.
Find the element that you want to modify. If the structure of your xml file is too complex, you can use xpath you find what you want.
Apply your modification to that element.
Update your xml file.
Here is a simple demo:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("file.xml"); // use LoadXml(string xml) to load xml string
string path = "/Installation/ServerIP";
XmlNode node = xmlDoc.SelectSingleNode(path); // use xpath to find a node
node.InnerText = "192.168.1.12"; // update node, replace the inner text
xmlDoc.Save("file.xml"); // save updated content
Hope it's helpful.
I have that xml document :
<?xml version="1.0" encoding="utf-8" ?>
<reminders>
<reminder>
<Title>Alarm1</Title>
<Description>Desc1</Description>
<Time>03/07/2012 10:11AM</Time>
<snooze>1</snooze>
<repeat>None</repeat>
</reminder>
<reminder>
<Title>Alarm2</Title>
<Description>Desc2</Description>
<Time>03/07/2012 10:11AM</Time>
<snooze>15</snooze>
<repeat>Daily</repeat>
</reminder>
</reminders>
And say i would like to create a full reminder child like :
<reminder>
<Title>NEW-Alarm</Title>
<Description>New-Desc</Description>
<Time>03/07/2012 10:11AM</Time>
<snooze>15</snooze>
<repeat>Daily</repeat>
</reminder>
How can i do that in C# ?
And also i`d like to edit some child like from :
<Title>NEW-Alarm</Title>
to be
<Title>Modified-NEW-Alarm</Title>
I am fresh to XML and i really did my best , actually i am opening like 13 webpages for xml but none of them has what i really need, so i`ll truly appreciate your help.
I would take a look at using XDocument. You may want to search the web for examples of creating XML with it but this answer from the unstoppable Jon Skeet is a good place to start:
XML file creation using XDocument in C#
Hope that helps.
Also see these links:
http://www.codeproject.com/Articles/169598/Parse-XML-Documents-by-XMLDocument-and-XDocument
http://www.leghumped.com/blog/2009/06/30/c-xml-with-xdocuments/
http://forums.asp.net/t/1736899.aspx/1?Help+using+XDocument+in+LINQ+with+ASP+Net+C+
Load the doc with XDocument class
Add a element (edit PATH with your data) :
XElement newEl = new XElement(new XElement("reminder",
new XElement("Title", "NEW-Alarm"),
new XElement("Description", "New-Desc"),
new XElement("Time", "03/07/2012 10:11AM"),
new XElement("snooze", "15"),
new XElement("repeat", "Daily")));
doc.Root.Add(newEl);
doc.Save(PATH);
To change, we must first find the element (with LINQ) and then apply the SetValue method.
http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.setvalue.aspx
You need to look into the XDocument as a way to open your XML Document and then take a look at the documentation for XElement to see how easy it is to build nodes.
Each documentation page has great samples.