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片段中,你没有定义名字空间前缀ssx对应的命名空间。 命名空间前缀只是给定元素的作用域内实际名称空间表的缩写查找。 因此如下

 <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"">&#45;&#45;-</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