如何移除XML特定子节点命名空间?Delphi导出Excel兼容问题
解决Delphi导出Excel兼容XML时节点命名空间问题
问题原因
你当前的代码错误地将<Style>及其子节点的命名空间指定为nso(urn:schemas-microsoft-com:office:office),而Excel要求<Styles>节点属于根节点的默认命名空间(urn:schemas-microsoft-com:office:spreadsheet),且内部的<Style>、<Alignment>等节点应使用ss前缀对应的命名空间。这种命名空间不匹配导致XML引擎自动给<Styles>节点添加了错误的xmlns属性,触发Excel打开错误。
修正后的代码
procedure TForm1.btnSaveClick(Sender: TObject); var XML : IXMLDOCUMENT; RootNode, CurNode, ChildNode, ChildNode2, ChildNode3 : IXMLNODE; ns, nso, nsx, nsss, nshtml : String; begin XML := NewXMLDocument; XML.Options := [doNodeAutoIndent]; ns := 'urn:schemas-microsoft-com:office:spreadsheet'; nso := 'urn:schemas-microsoft-com:office:office'; nsx:= 'urn:schemas-microsoft-com:office:excel'; nsss := 'urn:schemas-microsoft-com:office:spreadsheet'; nshtml := 'http://www.w3.org/TR/REC-html40'; RootNode := XML.AddChild('Workbook'); RootNode.DeclareNamespace('', ns); RootNode.DeclareNamespace('o', nso); RootNode.DeclareNamespace('x', nsx); RootNode.DeclareNamespace('ss', nsss); RootNode.DeclareNamespace('html', nshtml); // DocumentProperties节点处理(保持不变) CurNode := RootNode.AddChild('DocumentProperties'); CurNode.DeclareNamespace('', nso); ChildNode := CurNode.AddChild('Author', nso); ChildNode.Text := 'File Author'; ChildNode := CurNode.AddChild('LastAuthor', nso); ChildNode.Text := 'File Editor'; ChildNode := CurNode.AddChild('Created', nso); ChildNode.Text := DateToStr(Now); ChildNode := CurNode.AddChild('LastSaved', nso); ChildNode.Text := DateToStr(Now); ChildNode := CurNode.AddChild('Version', nso); ChildNode.Text := '16.00'; // OfficeDocumentSettings节点处理(保持不变) CurNode := RootNode.AddChild('OfficeDocumentSettings'); CurNode.DeclareNamespace('', nso); ChildNode := CurNode.AddChild('AllowPNG', nso); // ExcelWorkbook节点处理(保持不变) CurNode := RootNode.AddChild('ExcelWorkbook'); CurNode.DeclareNamespace('', nso); ChildNode := CurNode.AddChild('WindowHeight', nso); ChildNode.Text := '8976'; ChildNode := CurNode.AddChild('WindowWidth', nso); ChildNode.Text := '23040'; ChildNode := CurNode.AddChild('WindowTopX', nso); ChildNode.Text := '32767'; ChildNode := CurNode.AddChild('WindowTopY', nso); ChildNode.Text := '32767'; ChildNode := CurNode.AddChild('ProtectStructure', nso); ChildNode.Text := 'False'; ChildNode := CurNode.AddChild('ProtectWindows', nso); ChildNode.Text := 'False'; // Styles节点修正:继承根节点默认命名空间,无需额外声明 CurNode := RootNode.AddChild('Styles'); // Style节点改用ss命名空间(nsss),而非nso ChildNode := CurNode.AddChild('Style', nsss); ChildNode.Attributes['ss:ID'] := 'Default'; ChildNode.Attributes['ss:Name'] := 'Normal'; ChildNode2 := ChildNode.AddChild('Alignment', nsss); ChildNode2.Attributes['ss:Vertical'] := 'Bottom'; ChildNode2 := ChildNode.AddChild('Borders', nsss); ChildNode2 := ChildNode.AddChild('Font', nsss); ChildNode2.Attributes['ss:FontName'] := 'Calibri'; ChildNode2.Attributes['x:Family'] := 'Swiss'; ChildNode2.Attributes['ss:Size'] := '11'; ChildNode2.Attributes['ss:Color'] := '#000000'; ChildNode2 := ChildNode.AddChild('Interior', nsss); ChildNode2 := ChildNode.AddChild('NumberFormat', nsss); ChildNode2 := ChildNode.AddChild('Protection', nsss); ChildNode := CurNode.AddChild('Style', nsss); ChildNode.Attributes['ss:ID'] := 's64'; ChildNode2 := ChildNode.AddChild('Alignment', nsss); ChildNode2.Attributes['ss:Vertical'] := 'Center'; ChildNode2.Attributes['ss:WrapText'] := '1'; ChildNode2 := ChildNode.AddChild('Borders', nsss); ChildNode3 := ChildNode2.AddChild('Border', nsss); ChildNode3.Attributes['ss:Position'] := 'Right'; ChildNode3.Attributes['ss:LineStyle'] := 'Continuous'; ChildNode3.Attributes['ss:Weight'] := '1'; ChildNode3.Attributes['ss:Color'] := '#FFFFFF'; ChildNode2 := ChildNode.AddChild('Font', nsss); ChildNode2.Attributes['ss:FontName'] := 'Calibri'; ChildNode2.Attributes['x:Family'] := 'Swiss'; ChildNode2.Attributes['ss:Size'] := '11'; ChildNode2.Attributes['ss:Color'] := '#FFFFFF'; ChildNode2 := ChildNode.AddChild('Interior', nsss); ChildNode2.Attributes['ss:Color'] := '#44546A'; ChildNode2.Attributes['ss:Pattern'] := 'Solid'; ChildNode := CurNode.AddChild('Style', nsss); ChildNode.Attributes['ss:ID'] := 's65'; ChildNode2 := ChildNode.AddChild('Alignment', nsss); ChildNode2.Attributes['ss:Vertical'] := 'Center'; ChildNode2.Attributes['ss:WrapText'] := '1'; ChildNode2 := ChildNode.AddChild('Borders', nsss); ChildNode3 := ChildNode2.AddChild('Border', nsss); ChildNode3.Attributes['ss:Position'] := 'Left'; ChildNode3.Attributes['ss:LineStyle'] := 'Continuous'; ChildNode3.Attributes['ss:Weight'] := '1'; ChildNode3.Attributes['ss:Color'] := '#FFFFFF'; ChildNode3 := ChildNode2.AddChild('Border', nsss); ChildNode3.Attributes['ss:Position'] := 'Right'; ChildNode3.Attributes['ss:LineStyle'] := 'Continuous'; ChildNode3.Attributes['ss:Weight'] := '1'; ChildNode3.Attributes['ss:Color'] := '#FFFFFF'; ChildNode2 := ChildNode.AddChild('Font', nsss); ChildNode2.Attributes['ss:FontName'] := 'Calibri'; ChildNode2.Attributes['x:Family'] := 'Swiss'; ChildNode2.Attributes['ss:Size'] := '11'; ChildNode2.Attributes['ss:Color'] := '#FFFFFF'; ChildNode2 := ChildNode.AddChild('Interior', nsss); ChildNode2.Attributes['ss:Color'] := '#44546A'; ChildNode2.Attributes['ss:Pattern'] := 'Solid'; ChildNode := CurNode.AddChild('Style', nsss); ChildNode.Attributes['ss:ID'] := 's66'; ChildNode2 := ChildNode.AddChild('Alignment', nsss); ChildNode2.Attributes['ss:Vertical'] := 'Bottom'; ChildNode2.Attributes['ss:WrapText'] := '1'; XML.SaveToFile('export.xml'); end;
关键修改说明
- Styles节点:直接通过
RootNode.AddChild('Styles')添加,继承根节点的默认命名空间(urn:schemas-microsoft-com:office:spreadsheet),不会生成额外的xmlns属性。 - Style及子节点:将所有
AddChild时指定的命名空间从nso改为nsss(即与根节点默认命名空间一致的spreadsheet命名空间),确保这些节点属于ss前缀对应的命名空间,符合Excel的XML格式要求。
这样导出的<Styles>节点将不再带有任何xmlns属性,与模板文件一致,Excel可以正常打开该XML文件。
内容的提问来源于stack exchange,提问作者WackyWabbit
相关产品推荐
相关产品推荐

