locked
XmlElement.Attributes is dropping namespaces RRS feed

  • Question

  • Hi all;

    If you prefer as a fiddle - click here.

    In my debugger, I have an XmlElement.OuterXml of:

    <?xml version="1.0"?>
    <p:sld mc:Ignorable="p14 a14 p15 p16 a16 thm15 adec ahyp v"
      xmlns:v="urn:schemas-microsoft-com:vml"
      xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main"
      xmlns:ahyp="http://schemas.microsoft.com/office/drawing/2018/hyperlinkcolor"
      xmlns:adec="http://schemas.microsoft.com/office/drawing/2017/decorative"
      xmlns:thm15="http://schemas.microsoft.com/office/thememl/2012/main"
      xmlns:p16="http://schemas.microsoft.com/office/powerpoint/2015/main"
      xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" 
    

    Note it's mc:Ignorable, not Ignorable.

    I call XmlElement.Attributes and one of the attributes is for Ignorable but... enter image description here

    It's lost the prefix/namespace.

    Any idea what is going on here?

    ps- Also posted on StackOverflow, but the response there is it seems to be a bug.


    What we did for the last 6 months - Made the world's coolest reporting & docgen system even more amazing


    Monday, November 23, 2020 11:41 AM

All replies

  • Try an alternative to inner.SetAttribute:

    System.Xml.XmlDocument doc = new System.Xml.XmlDocument( );
    var root = doc.CreateElement( "root" );
    doc.AppendChild( root );
    
    const string ns = "http://schemas.openxmlformats.org/markup-compatibility/2006";
    
    root.SetAttribute( "xmlns:mc", ns );
    
    var inner = doc.CreateElement( "inner" );
    root.AppendChild( inner );
    
    var ignorable = doc.CreateAttribute( "mc", "Ignorable", ns );
    ignorable.Value = "p14 a14 p15 p16 a16 thm15 adec ahyp v";
    inner.Attributes.Append( ignorable );
    
    Console.WriteLine( doc.OuterXml );
    
    var list = inner.Attributes;
    foreach( System.Xml.XmlAttribute attr in list )
    	Console.WriteLine( attr.Name );

    The first SetAttribute can be replaced too.




    • Edited by Viorel_MVP Monday, November 23, 2020 5:37 PM
    Monday, November 23, 2020 5:36 PM
  • Hi;

    Thanks for the suggestion. Unfortunately, it would be a royal PITA to pass the XmlDocument down to the several hundred places we do this. Is there any way to get this working without the document?

    thanks - dave


    What we did for the last 6 months - Made the world's coolest reporting & docgen system even more amazing

    Monday, November 23, 2020 5:46 PM
  • Hi DavidThi808,

    Thanks for your feedback.

    I find that both solutions under this thread and in StackOverflow can successfully get the prefix of 'Ignorable' attribute.

    >>it would be a royal PITA to pass the XmlDocument down to the several hundred places we do this. Is there any way to get this working without the document?

    Could you provide more detailed descriptions about this? It will help us analyze your problem.

    We are waiting for your update.

    Best Regards,

    Xingyu Zhao


    Visual Basic and CLR forum will be migrating to a new home on Microsoft Q&A! (VB.NET and CLR) We invite you to post new questions in the new home on Microsoft Q&A ! For more information, please refer to the sticky post(VB.NET and CLR).

    Tuesday, November 24, 2020 7:28 AM
  • Hi Xingyu;

    I've found a way to do this, without have to pass the XmlDocument down.

    However, I think this is a bug. Can you please report it to the .Net team?

    thanks - dave


    What we did for the last 6 months - Made the world's coolest reporting & docgen system even more amazing

    Tuesday, November 24, 2020 12:21 PM
  • [EDIT: removed as I see where the problem is]

    I modified your example a bit to get the problem you said:

    using System;
    
    public class Program
    {
    	public static void Main()
    	{
    		System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
    		var root = doc.CreateElement("root");
    		root.SetAttribute("xmlns:mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
    		doc.AppendChild(root);
    		
    		System.Xml.XmlDeclaration xml_declaration;
            xml_declaration = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
    
            System.Xml.XmlElement document_element = doc.DocumentElement;
            doc.InsertBefore(xml_declaration, document_element);
    
    		var inner = doc.CreateElement("inner");
    		root.AppendChild(inner);
    		inner.SetAttribute("Ignorable", "http://schemas.openxmlformats.org/markup-compatibility/2006", "p14 a14 p15 p16 a16 thm15 adec ahyp v");
    
    		var list = inner.Attributes;
    		foreach (System.Xml.XmlAttribute attr in list)
    			Console.WriteLine(attr.Name);
    		
    		Console.WriteLine(doc.OuterXml);
    	}
    }

    In doc.OuterXml content, you can see the attribute is properly named "mc:Ignorable", yet attr.Name does not show it correctly.

    EDIT2: Now I get it to work as expected:

    using System;
    
    public class Program
    {
    	public static void Main()
    	{
    		const string ns = "http://schemas.openxmlformats.org/markup-compatibility/2006";
    		System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
    		var root = doc.CreateElement("root");
    		root.SetAttribute("xmlns:mc", ns);
    		doc.AppendChild(root);
    		
    		System.Xml.XmlDeclaration xml_declaration;
            xml_declaration = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
    
            System.Xml.XmlElement document_element = doc.DocumentElement;
            doc.InsertBefore(xml_declaration, document_element);
    
    		var inner = doc.CreateElement("inner");
    
    		var ignorable = doc.CreateAttribute( "mc", "Ignorable", ns );
    		ignorable.Value = "p14 a14 p15 p16 a16 thm15 adec ahyp v";
    		inner.Attributes.Append( ignorable );
    		
    		root.AppendChild(inner);
    		
    		var list = inner.Attributes;
    		foreach (System.Xml.XmlAttribute attr in list)
    			Console.WriteLine(attr.Name);
    	
    		Console.WriteLine(doc.OuterXml);
    	}
    }


    Wednesday, November 25, 2020 3:08 AM
    Answerer