4

I have an XElement that I need to create via dynamic xml literals/embedded expressions and I need it to inherit the default namespace. This doesn't appear possible though through everything I've tried. Does anyone know how to make this work?

For example

Imports <xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
Sub CreateXAML()
        Dim obj = "Rectangle"
        Dim objFill As String = obj & ".Fill"
        Dim myXML As XElement = <<%= obj %>><<%= objFill %>>no namespace</></>

        Dim myXML2 As XElement = <Path><Path.Fill>inherits namespace</Path.Fill></Path>
        MsgBox(myXML.ToString & vbCrLf & myXML2.ToString)
End Sub

The first one, myXML, is not created with the default ns, but the second one, myXML2, is.

Todd Main
  • 28,951
  • 11
  • 82
  • 146
  • 2
    I've been looking for a way to get an XElement without the default ns, so your question answers how to do that! – CoderDennis Feb 05 '10 at 13:45
  • 2
    Interesting that `Dim myXML As XElement = <<%= obj %>>no namespace>` doesn't even work, but produces a runtime exception. I've always thought the way xml literals inserted the namespace was strange. Haven't figured out how to control it yet. – CoderDennis Feb 05 '10 at 13:56
  • Yeah, at one time I was also looking for a way to create it without the default namespace, so it's actually a good technique. I'd just like to be able to flag it as "does need default ns" or something like that. – Todd Main Feb 05 '10 at 15:26
  • Your question isn't all that clear. Are you expecting the namespace to appear as an attribute of the xelement when the document is outputted? The way I believe it works is if you use xml literals and import the namespace as you have done, the namespace is only inserted at the top level node but is accessible at all node levels. I had the opposite problem to you I couldn't get rid of the namespace. Check this out http://stackoverflow.com/questions/1748003/linq-to-xml-and-namespace-prefixes – Andrew Feb 05 '10 at 16:02
  • 1
    The question is clear to me! :) Yes, I want the default namespace as an attribute of the top-most element. What you've stated is true for every situation, except for the one I've listed above. On your issue on the link, yes, it is expected behavior - you're going to need to list "vt" somewhere in your XNode. I'll post a solution on that page. – Todd Main Feb 05 '10 at 17:18
  • 1
    You might want to report this on the http://connect.microsoft.com site as a bug. Seems to me that the behavior should be the same both ways. – CoderDennis Feb 06 '10 at 05:41
  • @Otaku: please post the URL of your Connect bug report here, so that others can vote on how important they feel a fix would be. – John Saunders Feb 07 '10 at 04:01
  • Here it is: https://connect.microsoft.com/VisualStudio/feedback/details/531565/dynamic-xml-literals-dont-inherit-default-namespace. But based on the answer below, it doesn't appear to be a bug as much as a superb annonyance. – Todd Main Feb 07 '10 at 05:51

1 Answers1

3

This is documented http://msdn.microsoft.com/en-us/library/bb675177.aspx in the Global Namespaces and Embedded Expressions section that it won't work, but the article doesn't provide a workaround or solution. I had this need before too and just through trial and error, was able to get it to work by creating the element in advance with the namespace in tow, like this:

Imports <xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
Sub CreateXAML()
    Dim shape = "Rectangle"
    Dim obj = <<%= "{http://schemas.microsoft.com/winfx/2006/xaml/presentation}" & shape %>></>
    Dim objFill = <<%= "{http://schemas.microsoft.com/winfx/2006/xaml/presentation}" & shape %>></>
    Dim myXML As XElement = <<%= obj %>><<%= objFill %>>has namespace</></>

    Dim myXML2 As XElement = <Rectangle><Rectangle.Fill>inherits namespace</Rectangle.Fill></Rectangle>
    MsgBox(myXML.ToString & vbCrLf & myXML2.ToString)
End Sub

You may wonder why the "Imports" statement is still there. Well, it is used in the case of adding in a non-dynamic XElement to inherit the global namespace. Like this:

<<%= obj %>><<%= objFill %>><Text>has namespace</Text></></>
NakedBrunch
  • 48,713
  • 13
  • 73
  • 98
  • 1
    This is brilliant. I had not been able to find a way to get the xmlns in there without a run time error, like *Dim obj = <<%= shape %> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">>*. Great, great, great! – Todd Main Feb 07 '10 at 05:56
  • I just can't get over how great this is. It has cut my code by 50%! – Todd Main Feb 08 '10 at 23:47