【问题标题】:Why doesn't my code that uses System.Xml.XmlReader detect an invalid XML file?为什么我使用 System.Xml.XmlReader 的代码没有检测到无效的 XML 文件?
【发布时间】:2018-09-08 13:56:49
【问题描述】:

目标

使用 PowerShell 5.1,通过使用 Microsoft 的 System.Xml.XmlReader 对照 XML 架构对其进行验证来检测无效的 XML 文件。我将通过捕获XmlReader 引发的XML 解析错误的XMLException 来检测无效的XML 文件。

注意:我不想使用 PowerShell 社区扩展 Test-Xml cmdlet。

问题

在解析无效的 XML 文件时,$readerResult = $xmlReader.Read() 的代码行没有抛出我期望的 XMLException

参考文献

Validation Using the XmlSchemaSet

XmlReader Class

我的 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)
}

【问题讨论】:

  • 在第一个Read 之后,这不是表示到目前为止它所读取的只是 XML 声明,在我看来它的格式很好吗?
  • @Damien_The_Unbeliever 我的错误 - 我错误地认为任何人 Read 都会根据 xsd 验证整个 xml 文件。我现在了解到您需要从 xml 文件中Read 一行,以便验证该行。请注明作为答案,以便我接受。

标签: xml xsd-validation xmlreader


【解决方案1】:

XmlReader 概念的全部意义在于它是一种处理 XML 的方法。这使您可以访问大型/复杂的 XML 文档,而无需将整个内容保存在内存中(如果您使用 DOM 样式的访问,则需要启动几层额外的内存使用)。

这在内存使用方面是有效的,但确实意味着只有在遇到问题的节点时才会报告错误。

这里的第一个 Read 读取 XML 声明 - &lt;?xml version="1.0" encoding="UTF-8"?&gt; - 看起来格式正确,不应引发任何错误。如果您需要验证整个文档,那么您需要 Read 将其完全通过直到结束。但如果这是你的唯一目的,我可能会遵从例如Test-Xml 您要解除的命令行开关。

【讨论】:

  • 要明确一点:因此,读取整个文档所需的最少代码并让验证器有机会将每个 xml 片段与模式进行比较:while ($xmlReader.Read()) {}。此外,我的意图是根据架构验证 XML,然后读取 XML 并对其值执行处理。我对使用Test-Xml cmdlet 犹豫不决。我现在找不到它,但我遇到了一个 S.O.问答,其中一个答案描述了Test-Xml 未能检测到无效的 XML 块的特定场景。
  • @NovaSysEng - 我会说处理一次,做你需要做的任何实际处理。但是要为出现的错误情况做好准备,并告诉您整个文件无效。因此,在可能的情况下,避免“提交”基于 XML 的进一步操作(或有一个“撤消计划”),直到你到达终点。
猜你喜欢
  • 1970-01-01
  • 2021-05-26
  • 2011-08-21
  • 1970-01-01
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多