0

Having this kind of node (that we can find inside a .vbproj project file):

...
<ItemGroup>
    <Import Include="Microsoft.VisualBasic"/>
    <Import Include="Microsoft.Win32"/>
    <Import Include="Microsoft.Win32.SafeHandles"/>
    ...
</ItemGroup>
...

I declared a property in my class with a getter and a setter, to get a collection of the imports, or to replace the entire node content given a collection.

Well, the problem I have is that when I'm trying to replace the node content, my XmlWriter instance adds an additional and empty xmlns attribute, see this resulting example:

...
<ItemGroup>
    <Import Include="Microsoft.VisualBasic" xmlns="" />
    <Import Include="Microsoft.Win32" xmlns="" />
    <Import Include="Microsoft.Win32.SafeHandles" xmlns="" />
    ...
</ItemGroup>
...

Why happens that, and how to avoid it?.

I'm open to non-efficient solutions like a string replace (only on that node), however I tried it without success.

This is the relevant code I'm using:

Public Property ImportedNamespaces As SortedSet(Of String)
    Get
        Return New SortedSet(Of String)((From el As XElement In Me.ItemGroups()(1).Elements()
                                         Select el.@Include))
    End Get
    Set(ByVal value As SortedSet(Of String))
        Me.ItemGroups()(1).RemoveAll()

        Dim writer As XmlWriter = Me.ItemGroups()(1).CreateWriter
        For Each s As String In value
            With writer
                .WriteStartElement(Nothing, "Import", Nothing)
                .WriteAttributeString(Nothing, "Include", Nothing, s)
                .WriteEndElement()
            End With
        Next
        writer.Flush()
        writer.Close()

        ' This doesn't works.
        ' For Each el As XElement In Me.ItemGroups()(1).Elements("Import")
        '     el.Attribute("xmlns").Remove()
        ' Next

    End Set
End Property
3
  • Can you tell us what ItemGroups()(1) is, what kind of object is that, an XElement or XDocument? Commented May 26, 2016 at 12:42
  • @Martin Honnen Yes ItemGroups is a IEnumerable(Of XElement) then the indexer (1) returns a XElement. Thanks for comment!. Commented May 26, 2016 at 13:41
  • 1
    See my answer, you basically have to use the namespace of the parent node you want to insert the new element in, to avoid any xmlns="" undeclaration. Commented May 26, 2016 at 13:47

1 Answer 1

1

Assuming you have an XElement then you can either use .WriteStartElement(Nothing, "Import", Me.ItemGroups()(1).Name.NamespaceName) or you might want to replace the whole XmlWriter use by

Me.ItemGroups()(1).Add(From s As String In value Select New XElement(Me.ItemGroups()(1).Name.Namespace + "Import", New XAttribute("Include", s)))
Sign up to request clarification or add additional context in comments.

2 Comments

It is not the string concatenation operator that I used and suggested to use, it is the overload of + msdn.microsoft.com/en-us/library/… which allows you to "add" a string with a local name of an element to an XNamespace to construct an XName. Your edit with & would cause an error "BC30452 Operator '&' is not defined for types 'XNamespace' and 'String'.".
Sorry I didn't noticed is not the "NamespaceName" string property, totally my fault, Thanks again!.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.