0

I am working on a program in C# that edits open-document files on xml level. For example it adds rows to tables.

So I load the content.xml into an XmlDocument "doc" and traverse the xml structure. Say I have the <table:table-row> node in an XmlNode "row" and now I want to add a <table:table-cell> node to it. So I call

XmlDocument doc = new XmlDocument();
doc.Load(filename);
...
XmlNode row = ...;
...
XmlNode cell = doc.CreateElement("table:table-cell");
row.Append(cell);
...
doc.Save(filename);

The problem is that, in the file, the new node only contains <table-cell>...</table-cell>

C# just decides to ignore what I told it to and does something else without even telling me (at first I overlooked the problem and was wondering why it didn't work although the generated xml looked okay).

From what I gathered out so far, the problem has to do with the fact that "table:" is a namespace. When I also supply a NamespaceURI to CreateElement, I get <table:table-cell table:xmlns="THE_URI" >... - but the original document did not have this xmlns, so I don't want it either...

I tried to use an XmlTextWriter and setting writer.Settings.Namespaces = false, because I thought, this should suppress the output of the xmlns, but it only caused an exception - the document has some namespaces, which are forbidden if Namespaces is set to false... (wtf!? suppressing the output of xmlns seems a billion times more logical than throwing an exception if an xmlns is present...)

In some similar discussions I read that you should set the cell.Name manually, but this property is read-only... Others suggest to change it on text-file level (that's tinkering and it would be slow)

Can anyone give me a hint?

1
  • FYI, C# isn't ignoring anything. It's just the programming language. It's .NET that is ignoring you. It would have gladly ignored someone writing the same code in VB.NET. Commented Oct 17, 2013 at 18:05

2 Answers 2

2

Every namespace should have at least one xmlns definition with a URI. This is the ultimate differentiation between two tags.

You can however have the xmlns attribute declared only once in the file (in the beginning).

See Creating a specific XML document using namespaces in C#

Sign up to request clarification or add additional context in comments.

2 Comments

AH :-) the root-element DOES have xmlns entries for table etc - so I thought there would be no reason for the XML writer to put them in the successors again (since they should inherit the namespaces) UNLESS their namespace differs from the root elements xmlns... I got it working by passing the SAME namespace URI for the successor nodes - not just a random URI, so my call is now doc.CreateElement("table:table-cell", "urn:oasis:names:tc:opendocument:xmlns:table:1.0"); instead of doc.CreateElement("table:table-cell", "randomURI.com/table"); THANKS A LOT :-)
Actually, I read the xmlns:table attribute from the root-element and pass it to CreateElement (this way, the method is safe against namespace-changes in different versions)
0

The table: parts are not namespaces. They are "namespace prefixes". They are an alias for the actual namespace. They must be declared somewhere. If they are not declared at all in your source XML, then it is not valid XML, and you shouldn't expect to be able to process it.

Are you sure that what you have loaded is the entire XML document? They haven't left off parts to make it simpler? Those parts may be the ones that contain the definition of table:.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.