views:

625

answers:

4

I have the following XML:

<XMLDictionary>
  <a>b</a>
  <c>d</c>
  <e>f</e>
</XMLDictionary>

I'm trying to get the mappings a: b, c: d, e: f, and I can't quite find how to do it simply.

My current code looks like this:

 Do While reader.Read()
  If reader.NodeType = Xml.XmlNodeType.Element Then
   Me.Add(reader.Name, reader.ReadElementString)
  End If
 Loop

The problem is that I don't know how to read the contents of the element without calling ReadElementString, and ReadElementString advances the "pointer" to the next node (so reader.Name already has the next value). When in the loop I call Read() again, i'm skipping nodes.
I've tried several variations on this theme, and none works perfectly, which indicates that i'm missing something important here.

Any pointers?

Thanks

A: 

Try this (untested):

    Do While reader.Read()
            If reader.NodeType = Xml.XmlNodeType.Element Then
                    Me.Add(reader.Name, reader.Value)
            End If
    Loop
John Saunders
I don't see how that's any different from my code at all... In fact, just like my code, that skips over the middle XML entry, for the same reason.
Daniel Magliola
It _is_ your code, except that I saved off reader.Name before calling reader.ReadElementString.
John Saunders
John, I think what you are missing is that reader.Read() advances to the next node and so does reader.ReadElementString so basically Daniel's problem is that whenever he calls ReadElementString he is saying it advances to the next node. So he gets the node that he is on, it advances to the next node and then reader.Read() advances to the node after that. So he is only getting every other node. Seems weird though that ReadElementString does that.
Harv
That should be better. I thought he meant it read to the end element. At any rate what he wanted was Reader.Value, I believe.
John Saunders
I think we all came to the same conclusion, I just edited mine and saw you and another guy come up with that.
Harv
Unfortunately, Reader.Value is blank, so that doesn't work either :-(
Daniel Magliola
Right. I should know better: I always have to test XmlReader code. It needs the Read to move to the content, as James Conigliaro did above.
John Saunders
+1  A: 

I don't know if I would use the XmlReader for what you are doing, probably just an XmlDocument, but if you want the reader, probably something like this might work:

Dim lastNode As String = string.Empty
Do While reader.Read()
     If reader.NodeType = Xml.XmlNodeType.Element Then
        lastNode = reader.Name
     Else If reader.NodeType = Xml.XmlNodeType.Text AND NOT string.IsNullOrEmpty(lastNode) THEN
         Me.Add(lastNode,reader.Value)
         lastNode = string.Empty    
     End If
Loop

Forgive me for any syntax errors; it's been a while since of written in VB.net. This is a basic state machine that first detects if an Element is found and then starts looking for a text value.

James Conigliaro
That solves it, perfect! I just edited your answer a bit to fix one syntax error.Thank you!!
Daniel Magliola
Btw, I have to use the XML Reader, because my method is getting called in an XML Deserialization, and I'm getting an XML Reader as a parameter.
Daniel Magliola
A: 

How about using reader.ReadString() instead of reader.ReadElementString()? Or possibly instead of that just use reader.Value to get the value of the current node.

Harv
A: 
   Dim name As String
   Dim value As String

   While reader.Read()
        If reader.NodeType = XmlNodeType.Element Then
            name = reader.Name
            reader.Read()
            value = If((String.IsNullOrEmpty(reader.Value) OrElse reader.Value.Contains(Environment.NewLine)), "", reader.Value)
            Me.Add(name, value)
        End If
    End While
Russ Cam