在SaxonEE / dotNet中针对xsd验证xml时;如何调用SetInvalidityHandler?

时间:2018-07-17 05:35:17

标签: .net xml xsd saxon

我所拥有的是:“您可以调用SetInvalidityHandler(IInvalidityHandler inHandler)。这将导致每个有效性错误都报告给您提供的处理程序。该错误是通过(名称不正确)StaticError对象报告的。 Java ValidationFailure对象。”
我尝试过:(是的,是vb,c#的响应也可以)

extension AppDelegate: MessagingDelegate {

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
    //Here is your new FCM token
    print("Registered with FCM with token:", fcmToken)
}

然后一个子;

Delegate Sub ValidationCallBack(errH As Saxon.Api.IInvalidityHandler)
Dim IIH As Saxon.Api.IInvalidityHandler    'very suss on this line

然后是一个子包含;

Sub ValidationCallBackEvent(errH As Saxon.Api.IInvalidityHandler)
    dim k as integer
    k=0 'F9 here
End Sub

这没有错误,但是ValidationCallBackEvent也没有被提出,因此很明显我的管道不正确。

有什么想法吗?谢谢!

1 个答案:

答案 0 :(得分:0)

Saxon支持人员请张贴一个C#示例;

public void TestInvalidityHandler()
    {
        XmlReader xsd = XmlReader.Create(Path.GetFullPath(ConfigTest.DATA_DIR + "books.xsd"));
        XmlReader source_xml = XmlReader.Create(new StringReader("<?xml version='1.0'?><request><user_name>ed</user_name><password>sdsd</password><date1>a2009-01-01</date1><date2>b2009-01-01</date2></request>"));
        UriBuilder ub = new UriBuilder();
        ub.Scheme = "file";
        ub.Host = "";
        ub.Path = @"C:\work\tests\";
        Uri baseUri = ub.Uri;

        Processor saxon = new Processor(true);

        SchemaManager manager = saxon.SchemaManager;
        manager.ErrorList = new ArrayList();
        manager.XsdVersion = "1.0";
        try
        {
            DocumentBuilder builder = saxon.NewDocumentBuilder();
            builder.BaseUri = new Uri("http://example.com");
            XdmNode xsdNode = builder.Build(xsd);
            manager.Compile(xsdNode);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Schema compilation failed with " + manager.ErrorList.Count + " errors");
            String errors = "";
            foreach (StaticError error in manager.ErrorList)
            {
                Console.WriteLine("At line " + error.LineNumber + ": " + error.Message);
                errors += error.Message + "\n";
            }
            Assert.Fail("Failed in compile of xsd "+ errors);

        }
        Saxon.Api.SchemaValidator validator = manager.NewSchemaValidator();
        validator.SetInvalidityHandler(new MyInvalidaityHandler());
        validator.SetSource(source_xml);
        try
        {
            validator.Run();
            Assert.True(true);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.StackTrace);
            Assert.Fail(ex.Message);
        }
    }

    public class MyInvalidaityHandler : IInvalidityHandler
    {
        public XdmValue endReporting()
        {
            return currentNode; // this could be the entire  constructedreport
        }
        public void reportInvalidity(StaticError i)
        {
            //TODO - Do something here. Maybe write to a file or throw an exception 
        }
        public void startReporting(string systemId)
        {
            // no action, but can do setup of file
        }
    }
}

这足以让我获得可用的VB.net版本;

 Function TestInvalidityHandler() As String
    Dim sReturn As String
    Dim processor = New Processor(True)
    Dim sXmlPathUri As String
    Dim sXsdPathUri As String
    sXsdPathUri = "K:\SamplesFinal_ALL\IncludesImports\ALL\DotNetParserErrorTest\orderProd_YYNY_QQ.xsd"
    sXmlPathUri = "K:\SamplesFinal_ALL\IncludesImports\ALL\DotNetParserErrorTest\SampleFile_YYNY_QQ_dotNetValid.xml"
    processor.SetProperty("http://saxon.sf.net/feature/timing", "true")
    processor.SetProperty("http://saxon.sf.net/feature/validation-warnings", "false") ' //Set to true to suppress the exception

    Dim manager As SchemaManager = processor.SchemaManager
    manager.XsdVersion = "1.1"

    Dim schemaUri As System.Uri
    schemaUri = New System.Uri(sXsdPathUri)
    manager.Compile(schemaUri)                  'error handling removed for the moment..
    Dim validator As SchemaValidator = manager.NewSchemaValidator
    validator.SetInvalidityHandler(New MyInvalidityHandler())
    'use dot net objects;
    Dim settings As System.Xml.XmlReaderSettings = New System.Xml.XmlReaderSettings
    settings.DtdProcessing = System.Xml.DtdProcessing.Ignore
    Dim inputFileName As String = New Uri(sXmlPathUri).ToString()
    Dim xmlReader As System.Xml.XmlReader = System.Xml.XmlReader.Create(inputFileName, settings)
    validator.SetSource(xmlReader)
    Try
        validator.Run()
        sReturn = "OK"
    Catch ex As Exception
        sReturn = ex.Message
    End Try
    Return sReturn

End Function

Public Class MyInvalidityHandler

    Implements Saxon.Api.IInvalidityHandler

    Public Sub reportInvalidity(ByVal se As StaticError) Implements Saxon.Api.IInvalidityHandler.reportInvalidity
        'Get path etc from se.Message
    End Sub

    Public Sub startReporting(ByVal systemId As String) Implements Saxon.Api.IInvalidityHandler.startReporting
        'started
    End Sub

    Public Function endReporting() As XdmValue Implements Saxon.Api.IInvalidityHandler.endReporting
        Dim currentNode As XdmValue
        Return currentNode 'what's in xdm?
    End Function

End Class

因此不需要委托或接口,事实上,现在我已经找到了答案。 最后说明;感谢史蒂芬·多格特(Steven Doggart)的回答 Error that I must implement a function in a class even though function is defined。 对于接口“ Saxon.Api.IInvalidityHandler”,类“ MyInvalidityHandler”必须将“ Function endReporting()As XdmValue实现为XdmValue”,这是一小段时间的阻碍,这是这种情况下C#和VB.net之间的主要区别