Reputation: 40243
I'm a C# developer who's fumbling in the first VB code he's written since VB6, so if I am asking a rather obvious question, please forgive me.
I decided to experiment with XML Literals to generate some XML code for me, instead of using XMLDocument
I have 2 questions, the second regarding a workaround due to my inability to figure out the first.
1: Ideal solution
I have a Dictionary of ElementName, ElementValue whose KeyValue pairs I was looping over in the hope of generating the values dynamically, but the following syntax dies a horrible death
Dim xConnections As XElement
For Each connection As Connection In connections.AsList
For Each kvp As KeyValuePair(Of String, String) In connection.DecompiledElements
xConnections = <Connections> <<%= kvp.Key %>><%= kvp.Value %><\<%=kvp.Key %>> </Connections>
Next
Next
I have vague memories of the T4 syntax (the <%=%> syntax) being able to handle more complex operations (rather than direct assignment to the <%= ) and a 'Response.Write' like object to write output to, but I can't remember the details.
2: Cludgy workaround
Instead I thought of building a StringBuilder object and assigning its .ToString to the XElement, but that also failed with a conversion error.
I would prefer to continue using my key value pair concept in example one above, as I feel cludging together a string as in example 2 above is rather nasty, and I really should go back to using XMLDocument if instead.
Upvotes: 3
Views: 2170
Reputation: 4607
If I understand correctly what you are trying to do, you can use the StringBuilder. Use the StringBuilder.Append method and append the XmlElement 'OuterXml' property.
For example:
sb.Append(xmlElement.OuterXml)
Upvotes: 0
Reputation: 13837
VB.NET XML Literals are very powerful, but most often adding some LINQ to them makes them truly awesome. This code should do exactly what you're trying to do.
Dim Elements = New Dictionary(Of String, String)
Elements.Add("Key1", "Value1")
Elements.Add("Key2", "Value2")
Elements.Add("Key3", "Value3")
Dim xConnections = <Connections>
<%= From elem In Elements _
Select <<%= elem.Key %>><%= elem.Value %></> %>
</Connections>
The empty closing tag </>
is all that is needed for the vb compiler to properly construct an xml element whose name is generated from a value within a <%= %>
block.
Calling xConnections.ToString renders the following:
<Connections>
<Key1>Value1</Key1>
<Key2>Value2</Key2>
<Key3>Value3</Key3>
</Connections>
Upvotes: 7
Reputation:
To answer this more completely...
When injecting Strings into an XML Literal, it will not work properly unless you use XElement.Parse when injecting an XElement (this is because special characters are escaped)
So your ideal solution is more like this:
Dim conns = connections.AsList()
If conns IsNot Nothing AndAlso conns.length > 0 Then
Dim index = 0
Dim xConnections = _
<Connections>
<%= From kvp As KeyValuePair(Of String, String) In conns (System.Threading.Interlocked.Increment(index)).DecompiledElements() _
Select XElement.Parse("<" & <%= kvp.Key %> & ">" & <%= kvp.Value %> & "</" & <%= kvp.Key %> & ">") _
%>
</Connections>
Return xConnections.ToString()
End If
ToString will return the OuterXML Properly as a String (Value will not...) of course, just drop the ToString() if you want to return an XElement of
Since I don't know what AsList() does, nor do I know what DecompiledElements do, set your error trapping accordingly. There are other ways to do the loops as well, this is just one solution.
Upvotes: 0
Reputation: 71063
We would all be remiss not to mention that dynamic XML element names are generally a bad idea. The whole point of XML is to create a store a data structure in a form that is readily:
Dynamic element names fail that first condition. Why not simply use a standard XML format for storing key/value pairs like plists?
<dict>
<key>Author</key>
<string>William Shakespeare</string>
<key>Title</key>
<string>Romeo et</string>
<key>ISBN</key>
<string>?????</string>
</dict>
Upvotes: -3