【发布时间】: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
我的 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