我已经修改了 MSDN 的例子,以反映我的问题。
I have modified the MSDN example to reflect my problem.
当使用一个命名空间,我不能获取文档验证,因为我希望和验证文档时,这并不有它验证不管是否有其错误或没有命名空间。
When using a namespace I can't get the document to validate as I would expect and when validating a document that doesnt have a namespace it validates regardless of whether or not it has an error in it or not.
Dim errors As Boolean = False
Private Sub XSDErrors(ByVal o As Object, ByVal e As ValidationEventArgs)
Console.WriteLine("{0}", e.Message)
errors = True
End Sub
Private Function AddNameSpace(ByVal xDoc As XDocument, ByVal ns As XNamespace) As XDocument
For Each element As XElement In xDoc.Descendants
element.Name = ns + element.Name.LocalName
Next
Return xDoc
End Function
Sub Main()
Dim xsdMarkup As XElement = _
<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns="http://somenamespace.com" targetNamespace="http://somenamespace.com">
<xsd:element name='Root'>
<xsd:complexType>
<xsd:sequence>
<xsd:element name='Child1' minOccurs='1' maxOccurs='1'/>
<xsd:element name='Child2' minOccurs='1' maxOccurs='1'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Dim schemas As XmlSchemaSet = New XmlSchemaSet()
schemas.Add("http://somenamespace.com", xsdMarkup.CreateReader)
Dim doc1 As XDocument = _
<?xml version='1.0'?>
<Root>
<Child1>content1</Child1>
<Child2>content1</Child2>
</Root>
Dim doc2 As XDocument = _
<?xml version='1.0'?>
<Root>
<Child1>content1</Child1>
<Child3>content1</Child3>
</Root>
Dim ns As XNamespace = "http://somenamespace.com"
doc1 = AddNameSpace(doc1, ns)
Console.WriteLine("Validating doc1")
errors = False
doc1.Validate(schemas, AddressOf XSDErrors)
Console.WriteLine("doc1 {0}", IIf(errors = True, "did not validate", "validated"))
Console.WriteLine()
Console.WriteLine("Validating doc2")
errors = False
doc2.Validate(schemas, AddressOf XSDErrors)
Console.WriteLine("doc2 {0}", IIf(errors = True, "did not validate", "validated"))
End Sub
输出:
验证DOC1
元素'根'在命名空间http://somenamespace.com具有无效的子元素Child1在命名空间http://somenamespace.com。可能元素的列表预计:Child1。
The element 'Root' in namespace 'http://somenamespace.com' has invalid child element 'Child1' in namespace 'http://somenamespace.com'. List of possible elements expected: 'Child1'.
DOC1没有验证
验证DOC2
DOC2验证
那么你将需要添加将elementFormDefault =合格
来您的模式(在 XSD:架构
元素),如果你希望你的 DOC1
,你把命名空间的每个元素上是有效的。有了您的当前模式的有效实例将之一,在根
是目标名称,但 ChildX
元素中没有命名空间。
Well you will need to add elementFormDefault="qualified"
to your schema (on the xsd:schema
element) if you want your doc1
where you put the namespace on each element to be valid. With your current schema a valid instance would be one where the Root
is in the targetNamespace but the ChildX
elements are in no namespace.
第二个问题是一个已知的问题与模式验证和命名空间中,验证解析器查找匹配的模式根元素,如果是没有的,它确实宽松验证,所以你没有得到一个验证错误。使用的XmlReader API,你可以要求警告在这种情况下释放的,但是我不知道该怎么做,与验证方法。所以你需要code像
The second issue is a known problem with schema validation and namespaces, the validating parser looks for a matching schema for the root element, if there is none that it does lax validation so you don't get a validation error. With the XmlReader API you can ask for warning to be emitted in that case but I don't know how to do that with the Validate method. So you would need code like
Imports System
Imports System.Xml
Imports System.Xml.Linq
Imports System.Xml.Schema
Module Module1
Dim errors As Boolean = False
Private Sub XSDErrors(ByVal o As Object, ByVal e As ValidationEventArgs)
Console.WriteLine("{0}", e.Message)
errors = True
End Sub
Private Function AddNameSpace(ByVal xDoc As XDocument, ByVal ns As XNamespace) As XDocument
For Each element As XElement In xDoc.Descendants
element.Name = ns + element.Name.LocalName
Next
Return xDoc
End Function
Sub Main()
Dim xsdMarkup As XElement = _
<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns="http://somenamespace.com" targetNamespace="http://somenamespace.com" elementFormDefault="qualified">
<xsd:element name='Root'>
<xsd:complexType>
<xsd:sequence>
<xsd:element name='Child1' minOccurs='1' maxOccurs='1'/>
<xsd:element name='Child2' minOccurs='1' maxOccurs='1'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Dim schemas As XmlSchemaSet = New XmlSchemaSet()
schemas.Add("http://somenamespace.com", xsdMarkup.CreateReader)
Dim doc1 As XDocument = _
<?xml version='1.0'?>
<Root>
<Child1>content1</Child1>
<Child2>content1</Child2>
</Root>
Dim doc2 As XDocument = _
<?xml version='1.0'?>
<Root>
<Child1>content1</Child1>
<Child3>content1</Child3>
</Root>
Dim ns As XNamespace = "http://somenamespace.com"
doc1 = AddNameSpace(doc1, ns)
Console.WriteLine("Validating doc1")
errors = False
doc1.Validate(schemas, AddressOf XSDErrors)
Console.WriteLine("doc1 {0}", IIf(errors = True, "did not validate", "validated"))
Console.WriteLine()
Console.WriteLine("Validating doc2")
Dim xrs As New XmlReaderSettings()
xrs.ValidationType = ValidationType.Schema
xrs.ValidationFlags = xrs.ValidationFlags Or XmlSchemaValidationFlags.ReportValidationWarnings
xrs.Schemas = schemas
AddHandler xrs.ValidationEventHandler, AddressOf XSDErrors
errors = False
Using xr1 As XmlReader = doc2.CreateReader()
Using xr2 As XmlReader = XmlReader.Create(xr1, xrs)
While xr2.Read()
End While
End Using
End Using
Console.WriteLine("doc2 {0}", IIf(errors = True, "did not validate", "validated"))
End Sub
End Module