XDocument.Validate namespace problems

旧城冷巷雨未停 提交于 2019-12-05 21:04:28
Martin Honnen

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.

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!