【问题标题】:XMLReader IsElementEmpty is WrongXMLReader IsElementEmpty 错误
【发布时间】:2017-04-12 13:52:08
【问题描述】:

所以我正在构建一个小的 Windows 窗体应用程序,它允许您从 MSMQ 队列中选择一条消息,然后在对话框窗体上以格式良好的查看器显示 XML 消息。对话框窗体使用富文本框控件。

一旦消息的正文被读入 XMlDocument。我创建了这个扩展方法来添加换行符和格式:

    <Extension()>
    Public Function Beautify(doc As XmlDocument) As String
        Dim sb As New StringBuilder()
        Dim settings As New XmlWriterSettings()
        With settings
            .Indent = True
            .IndentChars = "     "
            .NewLineChars = Environment.NewLine
            .NewLineHandling = NewLineHandling.Replace
            .Encoding = New UTF8Encoding(False)
        End With

        Using writer As XmlWriter = XmlWriter.Create(sb, settings)
            If TypeOf doc.ChildNodes(0) Is XmlProcessingInstruction Then
                doc.RemoveChild(doc.ChildNodes(0))
            End If

            doc.Save(writer)
            Return sb.ToString()
        End Using
    End Function

我创建了一个 List(Of String) 以便可以选择多个消息,然后我将其传递给我的对话框表单的自定义构造函数:

Public Sub New(lMessages As List(Of String))

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Dim strLastMessage As String = lMessages.Last()
    For Each strMessage As String In lMessages
        Using reader As XmlReader = XmlReader.Create(New StringReader(strMessage))
            While reader.Read()
                Select Case reader.NodeType
                    Case XmlNodeType.XmlDeclaration
                        Me.rtbMessage.SelectionColor = Color.Blue
                        Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                        Me.rtbMessage.AppendText("<? " & reader.Name & " " & reader.Value & " ?>")

                    Case XmlNodeType.Element
                        Me.rtbMessage.SelectionColor = Color.Blue
                        Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                        Me.rtbMessage.AppendText("<")
                        Me.rtbMessage.SelectionColor = Color.Brown
                        Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                        Me.rtbMessage.AppendText(reader.Name)
                        If reader.HasAttributes Then
                            While reader.MoveToNextAttribute()
                                Me.rtbMessage.SelectionColor = Color.Brown
                                Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                                Me.rtbMessage.AppendText(" " & reader.Name)
                                Me.rtbMessage.SelectionColor = Color.Blue
                                Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                                Me.rtbMessage.AppendText("=" & Chr(34))
                                Me.rtbMessage.SelectionColor = Color.Black
                                Me.rtbMessage.SelectionFont = New Font(Me.rtbMessage.Font, FontStyle.Bold)
                                Me.rtbMessage.AppendText(reader.Value)
                                Me.rtbMessage.SelectionColor = Color.Blue
                                Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                                Me.rtbMessage.AppendText(Chr(34))
                            End While
                        End If
                        If reader.IsEmptyElement = True Then
                            Me.rtbMessage.SelectionColor = Color.Blue
                            Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                            Me.rtbMessage.AppendText(" />")
                        Else
                            Me.rtbMessage.SelectionColor = Color.Blue
                            Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                            Me.rtbMessage.AppendText(">")
                        End If

                    Case XmlNodeType.Text
                        Me.rtbMessage.SelectionColor = Color.Black
                        Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                        Me.rtbMessage.AppendText(reader.Value)

                    Case XmlNodeType.EndElement
                        Me.rtbMessage.SelectionColor = Color.Blue
                        Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                        Me.rtbMessage.AppendText("</")
                        Me.rtbMessage.SelectionColor = Color.Brown
                        Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                        Me.rtbMessage.AppendText(reader.Name)
                        Me.rtbMessage.SelectionColor = Color.Blue
                        Me.rtbMessage.SelectionFont = Me.rtbMessage.Font
                        Me.rtbMessage.AppendText(">")

                    Case XmlNodeType.Whitespace
                        Me.rtbMessage.AppendText(reader.Value)
                End Select
            End While
        End Using

        If strMessage <> strLastMessage Then
            Me.rtbMessage.AppendText(Chr(13) & Chr(10))
            Me.rtbMessage.AppendText(Chr(13) & Chr(10))
        End If
    Next
    Me.rtbMessage.Select(0, 0)
End Sub

现在大部分工作都很好,除了自动关闭元素没有关闭“/>”。我认为我检查 reader.IsEmptyElement 的 If-Then 语句可以解决问题,但事实并非如此。

以下是一个示例 XML 文件:

<Animal type="Mammal">
    <Classifications>
        <Classify name="CommonName" value="Dog" />
        <Classify name="Environment" value="Land" />
        <Classify name="NumLegs" value="4" />
    </Classifications>
</Animal>

如果您运行我的代码,您将看到“分类”元素在没有关闭标记的情况下呈现。

任何帮助将不胜感激!如果您更了解 C#,那么使用该语言的解决方案也可以。我可以转换!

【问题讨论】:

    标签: c# xml vb.net xml-parsing


    【解决方案1】:

    我想我想出了自己的问题!哈哈!

    只需要补充:

    reader.MoveToElement()
    

    就在我读完所有元素属性之后。读者不再在元素上,而是在最后一个属性上,因此 IsEmptyElement 为 False。如果我移回元素,则 IsEmptyElement 函数可以正常工作。

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多