Почему мой код, использующий System.Xml.XmlReader, не обнаруживает неверный файл XML? - PullRequest
0 голосов
/ 08 сентября 2018

Цель

Используя PowerShell 5.1, найдите недопустимый XML-файл, проверив его по XML-схеме, используя Microsoft System.Xml.XmlReader. Я обнаружу неверный XML-файл, перехватив XMLException, который XmlReader выдает ошибку синтаксического анализа XML.

Примечание. Я не хочу использовать расширения сообщества PowerShell Test-Xml командлет.

Проблема

Строка кода $readerResult = $xmlReader.Read() не выдает исключение XMLEx, которое я ожидаю при разборе неверного файла XML

Ссылки

Проверка с использованием XmlSchemaSet

Класс XmlReader

Мой XSD

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:config-file-schema">
  <xs:element name="notes">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="note" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="to"/>
              <xs:element name="from">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:byte" name="type" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element type="xs:string" name="heading"/>
              <xs:element type="xs:string" name="body"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Мой недопустимый XML (вторая строка использует фиктивное имя элемента notXXXes)

<?xml version="1.0" encoding="UTF-8"?>
<notXXXes xmlns="urn:config-file-schema">
    <note>
        <to>Tove</to>
        <from type="1">Jani</from>
        <heading>Reminder</heading>
        <body>Don't forget me this weekend!</body>
    </note>
    <note>
        <to>Bob</to>
        <from type="2">KeyW</from>
        <heading>Reminder</heading>
        <body>I won't</body>
    </note>
</notes>

Мой код

При запуске $readerResult возвращает true, указывая, что следующий узел был прочитан успешно. Я ожидаю, что $xmlReader.Read() выдаст XMLException, потому что содержимое файла XML нарушает схему.

cls
$error.clear()

try
{

    [System.Xml.Schema.XmlSchemaSet] $schemaSet = New-Object -TypeName System.Xml.Schema.XmlSchemaSet
    $schemaSet.Add("urn:config-file-schema","C:\Users\x\Desktop\test.xsd");

    [System.Xml.XmlReaderSettings] $readerSettings = New-Object -TypeName System.Xml.XmlReaderSettings
    $readerSettings.Schemas = $schemaSet
    $readerSettings.ValidationType = [System.Xml.ValidationType]::Schema
    $readerSettings.ConformanceLevel = [System.Xml.ConformanceLevel]::Fragment
    $readerSettings.IgnoreWhitespace = $true;
    $readerSettings.IgnoreComments = $true;

    [System.Xml.XmlReader]$xmlReader = [System.Xml.XmlReader]::Create("C:\Users\x\Desktop\test.xml", $readerSettings);

    #just to show that Schemas was set up OK
    "target namespace: " + $readerSettings.Schemas.Schemas().TargetNamespace

    $readerResult = $xmlReader.Read()

    "readerResult: " + $readerResult
}
catch
{
    "error: " + $error
}
finally
{
    $xmlReader.Close()
}

Редактировать # 1

Этот фрагмент будет читать каждую строку XML из файла и отображать его метаданные

while ($xmlReader.Read())
{
    write-console ("Depth:{0,1} Name:{1,-10} NodeType:{2,-15} Value:{3,-30}" -f $xmlReader.Depth, $xmlReader.Name, $xmlReader.NodeType, $xmlReader.Value)
}

1 Ответ

0 голосов
/ 08 сентября 2018

Суть концепции XmlReader в том, что это потоковый подход к работе с XML. Это позволяет вам получать доступ к большим / сложным XML-документам без необходимости хранить все содержимое в памяти (и, если вы используете доступ в стиле DOM, несколько уровней дополнительного использования памяти для загрузки).

Это эффективно с точки зрения использования памяти, но означает, что ошибки сообщаются только при обнаружении проблем с узлами.

Первый Read здесь читает XML-декларацию - <?xml version="1.0" encoding="UTF-8"?> - которая выглядит правильно сформированной и не должна вызывать каких-либо ошибок. Если вам нужно проверить весь документ, вам нужно будет полностью 1010 * пройти до конца. Но если это ваша только цель, я бы, вероятно, отложил, например, Test-Xml командлет, который вы отклоняете.

...