XMLDocument.Importnode失败
我目前正在一个项目,我必须创buildXMLNodes并将其插入到XML文件中的特定位置。
XMLNode是一个有大约90个单元格的行。
<Row ss:AutoFitHeight=\"0\"> <Cell ss:StyleID=\"s77\"><Data ss:Type=\"String\">ABC</Data></Cell> <Cell><Data ss:Type=\"Number\">100</Data></Cell> <Cell ss:StyleID=\"s77\"><Data ss:Type=\"String\">ABC</Data></Cell> <Cell><Data ss:Type=\"String\" x:Ticked=\"1\">---</Data></Cell> </Row>
我通过Stringbuilder创build文档,并用下面的代码读取它们:
using (StringReader sr = new StringReader((sbuilder.ToString()))) using (XmlTextReader xtr = new XmlTextReader(sr) { Namespaces = false }) { xdoc.Load(xtr); }
我想要添加节点的XML文件是一个带有3个选项卡的Excel 2003工作表,但我只需要第一个。 我加载它在:
XmlDocument xtemplate = new XmlDocument(); xtemplate.Load(file);
并尝试将我的节点导入模板XML
XmlNode tempnode = xtemplate.ImportNode(xdoc.DocumentElement, true);
在这里,我得到一个XmlException
字符hex值0x3A的':'不得包含在名称中。
我不知道这是从哪里来的。 没有单元格或行得到一个自定义的名称,我找不到一个名称,其中包含任何东西,但字母(除了文档的'#文档'作为名称)
我希望有人也经历过这个例外,可以帮助我理解,所以我可以解决我的问题。
我希望你能明白我的问题是什么,如果不是,我会尽我所能解释更好。 我的英语有点生疏,如果我屠杀了它,那么我的英语就有点儿怜悯了。
更新:
现在正在使用来自@dbc的解决scheme和一个litte Addition:
string innerXml = @"<Row xmlns=""urn:schemas-microsoft-com:office:spreadsheet"" xmlns:o=""urn:schemas-microsoft-com:office:office"" xmlns:x=""urn:schemas-microsoft-com:office:excel"" xmlns:ss=""urn:schemas-microsoft-com:office:spreadsheet"" xmlns:html=""http://www.w3.org/TR/REC-html40"" ss:AutoFitHeight=""0""> <Cell ss:StyleID=""s77""> <Data ss:Type=""String"">ABC</Data> </Cell> <Cell> <Data ss:Type=""Number"">100</Data> </Cell> <Cell ss:StyleID=""s77""> <Data ss:Type=""String"">ABC</Data> </Cell> <Cell> <Data ss:Type=""String"" x:Ticked=""1"">---</Data> </Cell> </Row>"; var xdoc = new XmlDocument(); xdoc.LoadXml(innerXml); // Do not use new XmlTextReader(sr) { Namespaces = false }) XmlDocument xtemplate = new XmlDocument(); // Load xtemplate from file as before XmlNode tempnode = xtemplate.ImportNode(xdoc.DocumentElement, true); // Insert into Target Document tempnode.ChildNodes[0].ParentNode.Attributes.RemoveAt(0); // Times 5 to delete all Namespacedefinitions
问题是,在你的XML片段中,你没有定义名字空间前缀ss
和x
对应的命名空间。 命名空间前缀只是给定元素的作用域内实际名称空间表的缩写查找。 因此如下
<ss:Row xmlns:ss="http://somenamespace"/> <xxxx:Row xmlns:xxxx="http://somenamespace"/> <Row xmlns="http://somenamespace"/>
都定义了相同的东西 – 一个名为{http://somenamespace}Row
的XML元素。
当ImportNode
将你的节点从一个文档复制到另一个时,它试图将旧文档中的命名空间前缀映射到新文档,以保留每个节点的实际名称空间 – 但是你的前缀缺less它们的定义,因此映射不能执行抛出exception。
要解决此问题,您必须将正确的名称空间定义添加到您的XML片段,与Excel 2003 XML格式所使用的一致。 Office 2003:XML参考架构将告诉您正确的名称空间。 这样做之后,应该使用XmlDocument.LoadXml()
加载XML片段,然后ImportNode
的exception将消失。
例如:
string innerXml = @"<Row xmlns=""urn:schemas-microsoft-com:office:spreadsheet"" xmlns:o=""urn:schemas-microsoft-com:office:office"" xmlns:x=""urn:schemas-microsoft-com:office:excel"" xmlns:ss=""urn:schemas-microsoft-com:office:spreadsheet"" xmlns:html=""http://www.w3.org/TR/REC-html40"" ss:AutoFitHeight=""0""> <Cell ss:StyleID=""s77""> <Data ss:Type=""String"">ABC</Data> </Cell> <Cell> <Data ss:Type=""Number"">100</Data> </Cell> <Cell ss:StyleID=""s77""> <Data ss:Type=""String"">ABC</Data> </Cell> <Cell> <Data ss:Type=""String"" x:Ticked=""1"">---</Data> </Cell> </Row>"; var xdoc = new XmlDocument(); xdoc.LoadXml(innerXml); // Do not use new XmlTextReader(sr) { Namespaces = false }) XmlDocument xtemplate = new XmlDocument(); // Load xtemplate from file as before XmlNode tempnode = xtemplate.ImportNode(xdoc.DocumentElement, true); // No exception