简体   繁体   中英

Generate XML in C# Using Specific XML Namespace

Target XML I am trying to achieve:

<Row><Data ss:Type="String">value</Data></Row>

Output I am currently getting:

<Row xmlns=""><Data Type="Number">0</Data></Row>

I am trying to create that target XML code using the System.Xml library, but the namespace prefix is not showing up when I create new elements. Snippet of the code that is generating the above output:

XmlElement eRow = xDoc.CreateElement("Row");
XmlElement eData = xDoc.CreateElement("Data");
XmlAttribute xAt = xDoc.CreateAttribute("ss", "Type", null);
xAt.Value = "Number";
eData.Attributes.Append(xAt);
eData.InnerText = "0";
eRow.AppendChild(eData);

I am trying to append this XML to a file that already exists. I have loaded the file as

XmlDocument xTemp = new XmlDocument();
xTemp.Load(templatePath);

and there are already namespaces in DocumentElement.Attributes that have already declared the prefix that I want to use: <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"> . Essentially, I am trying to get the "ss" prefix to show up before "Type" like in the target I provided above. Additionally, the output is displaying xmlns="" as an attribute in the "Row" tag, something that I never added. I assume these are both issues with the namespace not being declared, but as mentioned above, it should already be declared in the original document that I loaded.

How can I generate the target XML code I want?

You have created your attribute xAt without specifying the namespace uri, which is equivalent to empty string namespace uri (see the corresponding MSDN doc here ), that is certainly why you get the <Row xmlns="">

Actually you need to specify the exact namespace uri for it to work as you expect it. Let me illustrate using the namespace uri you have given in your question (Illustration very similar to your initial code but might have a few small differences that you can easily modify).

String namespaceUri = "urn:schemas-microsoft-com:office:spreadsheet";
XmlDocument xDoc = new XmlDocument();

XmlElement workbook = xDoc.CreateElement("ss", "Workbook", namespaceUri);
XmlElement rows = xDoc.CreateElement("Rows");

At this step I can assume that I have an XmlDocument similar to what you have after initially loading your file. My XmlDocument has the workbook node as its DocumentElement, it uses the given prefix and namespace uri.

Now we can create the attribute:

var attribute = xDoc.CreateAttribute("ss", "Type", "urn:schemas-microsoft-com:office:spreadsheet");
attribute.Value = "String";

The namespace uri should be specified correctly otherwise it won't be correctly rendered. When this attribute is used, since the namespace it is refering to is found on the nesting element (workbook), it is not necessary to mention it again here, and the framework will automatically remove the reference to the namespace uri.

Now we can go ahead and create the Row and data elements and add the attribute to the collection of attributes of the Data element.

XmlElement eRow = xDoc.CreateElement("Row");
XmlElement eData = xDoc.CreateElement("Data");

eData.Attributes.Append(attribute);
eData.InnerText = "value";
eRow.AppendChild(eData);

rows.AppendChild(eRow);
workbook.AppendChild(rows);

xDoc.AppendChild(workbook);

We can then display the document, for example with:

Console.WriteLine(xDoc.OuterXml);

Result:

<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"><Rows><Row><Data ss:Type="String">value</Data></Row></Rows></ss:Workbook>

I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM