Reputation: 12470
I am trying to add a prefix onto a few xmlnodes within a new XMLDocument (Created 100% from scratch, not loaded from a file etc).
In the simplest terms I have this :
XmlDocument doc = new XmlDocument();
XmlElement RootElement = (XmlElement)doc.AppendChild(doc.CreateElement("root"));
foreach (string line in CSV)
{
XmlElement navPointElement = (XmlElement) RootElement.AppendChild(doc.CreateElement("navPoint"));
XmlElement navPointTypeElement =(XmlElement) navPointElement.AppendChild(doc.CreateElement("type"));
navPointTypeElement.Prefix = "acp";
navPointTypeElement.InnerText = nodeCount == 0 ? "cover" : "article";
}
There is much more code but this gives you an idea of what I'm doing. Now the document outputs fine, but it completely skips over the prefix declarations. I have read around about defining namespaces, and I tried to the following to no avail.
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("acp", "http://www.namespace.com");
I'm sure it's something simple, but I can't quite find any documentation on it. The MSDN documentation for xmldocument prefix simply just adds the prefix much the same as I have done without the need for namespaces (Or atleast that's how they show it in their code samples).
Any help is much appreciated :)
Upvotes: 1
Views: 6519
Reputation: 87228
Well, you do need a namespace. Something like <acp:type/>
is invalid by itself because acp
doesn't map to any namespace, which is what a prefix should do.
What you need to do is to set the namespace on the element you want to add on the call of CreateElement for the type
element.
public class StackOverflow_10807173
{
public static void Test()
{
XmlDocument doc = new XmlDocument();
XmlElement RootElement = (XmlElement)doc.AppendChild(
doc.CreateElement("root"));
string[] CSV = "hello world how are you".Split(' ');
int nodeCount = 0;
XmlAttribute xmlnsAttr = doc.CreateAttribute(
"xmlns", "acp", "http://www.w3.org/2000/xmlns/");
string acpNamespace = "http://www.namespace.com";
xmlnsAttr.Value = acpNamespace;
RootElement.Attributes.Append(xmlnsAttr);
foreach (string line in CSV)
{
XmlElement navPointElement = (XmlElement)RootElement.AppendChild(
doc.CreateElement("navPoint"));
XmlElement navPointTypeElement = (XmlElement)navPointElement.AppendChild(
doc.CreateElement("type", acpNamespace)); // namespace here
navPointTypeElement.Prefix = "acp";
navPointTypeElement.InnerText = nodeCount == 0 ? "cover" : "article";
}
Console.WriteLine(doc.OuterXml);
}
}
One note: you don't really need to add the namespace in the root element; it's just that if you don't do that, you'll have the xmlns:acp="yournamespace"
attribute in all of the type
elements (since that prefix isn't in scope). Adding that in a parent element makes adding it in the children elements unecessary.
Upvotes: 4
Reputation: 73564
I had a similar issue, and I found the built-in .NET System.XML objects to be unable to do what I needed.
I needed to use the NAXML markup to create fuel price change records in our POS system. SOME of the elements needed a "nax" prefix, while others didn't. The System.Xml objects seemed to want to add it to all elements or none. I couldn't get it to just apply them to the elements I needed.
Because the System.XML objects didn't give me the granular control I needed, I ended up having to write out the Xml manually using a System.Text.StringBuilder.
Sample code from my app to give you an idea of how to do it:
System.Text.StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n");
sb.Append("<FuelPriceMaintenanceRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.POSVENDOR.com/NAXML-Extension\" xmlns:nax=\"http://www.naxml.org/POSBO/Vocabulary/2003-10-16\" xsi:schemaLocation=\"http://www.POSVENDOR.com/NAXML-Extension FuelPriceMaintenance.xsd\">\r\n");
sb.Append(" <nax:TransmissionHeader>\r\n");
sb.Append(" <nax:StoreLocationID>" + StoreNumber.ToString() + "</nax:StoreLocationID>\r\n");
sb.Append(" </nax:TransmissionHeader>\r\n");
...snip...
sb.Append("</FuelPriceMaintenanceRequest>");
Upvotes: 1