XMLDocument.Importnode fails

a 夏天 提交于 2020-01-15 07:37:12

问题


i´m currently working on a Project where i have to create XMLNodes and insert them at specific places in the XML File.

The XMLNode is a Row with around 90 Cells.

<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\">&#45;&#45;-</Data></Cell>
</Row>

I create the Document via Stringbuilder and read them in with:

    using (StringReader sr = new StringReader((sbuilder.ToString())))
    using (XmlTextReader xtr = new XmlTextReader(sr) { Namespaces = false })
    {
        xdoc.Load(xtr);
    }

The XML File where i want to add my nodes is an Excel 2003 Sheet with 3 Tabs but i only Need the first one. I load it in with:

    XmlDocument xtemplate = new XmlDocument();
    xtemplate.Load(file);

and try to Import my Node into the Template XML

XmlNode tempnode = xtemplate.ImportNode(xdoc.DocumentElement, true);

And here i get an XmlException

The ':' - characters Hex value 0x3A, shall not be included in a name.

I don´t have a clue where this is comming from. No cell or row gets a custom name and i could not find a name which contained anything but letters (Except the document which has '#document' as Name)

I hope someone has experienced this Exception too and could help me understand it so i can solve my problem.


I hope you can understand what my Problem is, if not i will try my best to explain it better. My English is a bit rusty so pleasy have mercy if i butchered it.

Update:

It is now working with the Solution from @dbc and a 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"">&#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); 
// Insert into Target Document
tempnode.ChildNodes[0].ParentNode.Attributes.RemoveAt(0); // Times 5 to delete all Namespacedefinitions

回答1:


The problem is that, in your XML fragment, you did not define the namespaces corresponding to the namespace prefixes ss and x. A namespace prefix is just an abbreviated lookup into the table of actual namespaces in scope for a given element. Thus the following

<ss:Row xmlns:ss="http://somenamespace"/>
<xxxx:Row xmlns:xxxx="http://somenamespace"/>
<Row xmlns="http://somenamespace"/>

all define the same thing -- an XML element named {http://somenamespace}Row.

When ImportNode copies your nodes from one doc to another, it tries to map the namespace prefixes from old doc to the new doc to preserve the actual namespace of each node -- but your prefixes are missing their definitions, hence the mapping cannot be performed and an exception is thrown.

To correct this you must add the correct namespace definitions to your XML fragment, consistent with those used by the Excel 2003 XML format. The Office 2003: XML Reference Schemas will tell you the correct namespaces. Having done so, you should use XmlDocument.LoadXml() to load the XML fragment, and then the exception from ImportNode will go away.

For instance:

        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


来源:https://stackoverflow.com/questions/28857669/xmldocument-importnode-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!