LoadXml - данные на корневом уровне недействительны.Линия 1, позиция 1 - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть схема, которая проверяет мой XML-файл, но я хочу сделать дополнительные проверки, такие как числовые диапазоны, структура дня рождения, например.ДД / ММ / ГГ, не мм / дд / гг.имя студента позволяет для специальных символов, например._ в имени и т. д. в тот момент, когда я запускаю свой код, я получаю сообщение об ошибке:
[Ошибка]: данные на корневом уровне недействительны.Строка 1, позиция 1. в System.Xml.XmlTextReaderImpl.Throw (Exception e)

образец моего xml:

 <?xml version="1.0" encoding="us-ascii" standalone="yes"?>
  <studentTable xmlns="namespace">

    <student>
      <ID>0</ID>
      <student_name>John</student_name>
      <birthday>25/09/1997</birthday>
    </student>

Я пробовал следующий код, но получаю ошибку «Данныена корневом уровне недопустим. Строка 1, позиция 1. в System.Xml.XmlTextReaderImpl.Throw (Exception e) "

        Dim xdoc As XmlDocument
        Dim nodelist As XmlNodeList
        Dim node As XmlNode
        Dim ID, birthday, student_name As String

        xdoc = New XmlDocument

        xdoc.LoadXml("student2.xml")

        nodelist = xdoc.SelectNodes("/studentTable/student")

        For Each node In nodelist

            ID = node.ChildNodes.Item(0).Attributes.GetNamedItem("ID").Value
            birthday = node.ChildNodes.Item(1).Attributes.GetNamedItem("birthday").Value
            student_name = node.ChildNodes.Item(2).Attributes.GetNamedItem("student_name").Value

        Dim rgx As New Regex("^[0-9]*$")
            If rgx.IsMatch(ID) = False Then
                lstErrs.Add("Invalid ID number")
            End If

        Dim reg As New Regex("^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$")
            If reg.IsMatch(birthday) = False Then
                lstErrs.Add("Invalid birthday")
            End If

        Dim regx As New Regex("^[a-zA-Z]+(([',. -][a-zA-Z ])?[a-zA-Z]*)*$")
            If regx.IsMatch(student_name) = False Then
                lstErrs.Add("Invalid Name")
            End If

        Next

xml error

        If lstErrs.Count > 0 Then

                '-- Output list of errors
                MsgBox("Complete but with errors! Check error file.") '& vbCrLf & vbCrLf & Strings.Join(lstErrs.ToArray, vbCrLf))
                fileWriter.WriteLine("Filename:   " & strFilNme)
                fileWriter.WriteLine(vbCrLf)
                fileWriter.WriteLine("Errors:")
                For i As Integer = 0 To lstErrs.Count - 1
                    fileWriter.WriteLine(lstErrs(i))
                Next
            Else
                MsgBox("Complete!")
            Exit Sub
        End If

        fileWriter.Close()


    Catch ex As XmlSchemaValidationException
            MsgBox("Complete but with errors! Check error file.")
            fileWriter.WriteLine("[Error]: XmlSchemaValidationException -error!!!!!!")
            fileWriter.WriteLine("LineNumber = {0}", ex.LineNumber)
            fileWriter.WriteLine("LinePosition = {0}", ex.LinePosition)
            fileWriter.WriteLine("Message = {0}", ex.Message)
            fileWriter.WriteLine("Source = {0}", ex.Source)

        Catch exOther As Exception
            MsgBox("Complete but with errors! Check error file.")
            fileWriter.WriteLine("[Error]: " & exOther.Message & exOther.StackTrace)

        Finally

            If Not IsNothing(reader) Then
            reader.Close()
        End If

        If Not IsNothing(fileWriter) Then
            fileWriter.Close()
        End If

    End Try

End Sub

Private Sub ValidationEventHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)



'MsgBox("Display Errors")
    Select Case e.Severity
        Case XmlSeverityType.Error
            lstErrs.Add("Error: {0} " & e.Message)
        Case XmlSeverityType.Warning
            lstErrs.Add("Warning {0} " & e.Message)
        Case Else
            lstErrs.Add(e.Message)

    End Select
End Sub

Я попытался изменить LoadXml, чтобы просто загрузить, но затем мой код работает без ошибок, но мое регулярное выражение не проверяет значения xml.любая помощь будет большой благодарностью.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Поскольку вы знаете, что в каждом <student> узле есть только один <ID>, <birthday> и т. Д., Вы можете использовать SelectSingleNode.

Хотя, похоже, .Value даст вамто, что кажется значением, это более рискованно: Значение XmlNode против InnerText .

Я полагаю, вы вставили xmlns="namespace", увидев похожие вещи в другом XML.В этом случае, если вы на самом деле не используете его, это только усложнит ситуацию.

Чтобы проверить дату, используйте DateTime.TryParseExact и задайте ей строку формата - нет необходимости в сложном регулярном выражении, которое потребовало быбыть другим, если вы изменили формат даты на yyyy-MM-dd.

Вы также можете объявить регулярные выражения вне цикла, чтобы код внутри цикла был немного более аккуратным.

Всегда неприятно получать сообщение, которое говорит что-то вроде «Ошибка даты», когда оно не сообщает вам, где или каковы ошибочные данные.

Итак, этот файл XML находится в моем «C»:Каталог \ Temp (я не знаю, почему вы бы использовали «us-ascii» вместо «utf-8»):

<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
<studentTable>
    <student>
        <ID>0q</ID>
        <student_name>John*</student_name>
        <birthday>25/109/1997</birthday>
    </student>
</studentTable>

и это консоль приложение:

Imports System.Text.RegularExpressions
Imports System.Xml

Module Module1

    Sub Main()
        Dim lstErrs As New List(Of String)

        Dim idRegex = New Regex("^[0-9]*$")
        Dim nameRegex = New Regex("^[a-zA-Z]+(([',. -][a-zA-Z ])?[a-zA-Z]*)*$")
        Dim dateFormat = "d/M/yyyy"

        Dim xdoc As New XmlDocument()
        xdoc.Load("C:\Temp\students.xml")

        Dim nodelist = xdoc.SelectNodes("//studentTable/student")

        For Each node As XmlNode In nodelist

            Dim id = node.SelectSingleNode("//ID").InnerText
            Dim dob = node.SelectSingleNode("//birthday").InnerText
            Dim name = node.SelectSingleNode("//student_name").InnerText

            If Not idRegex.IsMatch(id) Then
                lstErrs.Add("Invalid ID number " & id)
            End If

            If Not DateTime.TryParseExact(dob, dateFormat, Nothing, Nothing, New DateTime) Then
                lstErrs.Add("Invalid birthday " & dob)
            End If

            If Not nameRegex.IsMatch(name) Then
                lstErrs.Add("Invalid Name " & name)
            End If

            Console.WriteLine($"{id} {dob} {name}") '' for checking

        Next

        Console.WriteLine(String.Join(vbCrLf, lstErrs)) '' show the errors

        Console.ReadLine()

    End Sub

End Module

Я получил этот вывод:

0q 25/109/1997 John*
Invalid ID number 0q
Invalid birthday 25/109/1997
Invalid Name John*
0 голосов
/ 25 февраля 2019

Ни при каких обстоятельствах не пытайтесь анализировать XML с помощью регулярного выражения, если вы не хотите вызывать обряд 6 6 6 Ph'nglui mglw 'nafh Cthulhu R'lyeh wgah'nagl fhtagn.

Используйте библиотеку разбора XML, см. эту страницу , чтобы узнать, как это сделать с помощью C # .Net.Это должно быть преобразовано в vb.Net

Редактировать: в дополнение к комментариям.Попробуйте использовать XML-схему для проверки данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...