简体   繁体   中英

Is it possible to get <value-of select=''xpath here''> values from a schematron assert with libxml2 C API?

Note: I'm a beginner with these technologies.

I made a a.sch (schematron file) and b.xml which I'm validating with libxml2 C API. Everything is working good except that I don't see the values of <value-of select=''xpath here''> in my assert messages. I'm using the xmllint application which can be found in the libxml2 git repository ( https://git.gnome.org/browse/libxml2 ). The command line and results are shown at the end of this post.

If I take the same files and I use the following python code I'm able to see the values in the assert message.

#!/usr/bin/env python

from lxml import isoschematron
from lxml import etree

def runsch(rulesFile, xmlFile):

    # open files
    rules = open(rulesFile, 'r') # Schematron schema
    XMLhere = open (xmlFile, 'r') # XML to be checked

    # Parse schema
    sct_doc = etree.parse(rules)
    schematron = isoschematron.Schematron(sct_doc, store_report = True)

    # Parse xml
    doc = etree.parse(XMLhere)

    # Validate against schema
    validationResult = schematron.validate(doc)
    report = schematron.validation_report

    # Check result
    if validationResult:
        print("passed")
    else:
        print("failed")
        print(report)

        reportFile = open('report.html', 'wb')
        report.write(reportFile)

def main():
    runsch('a.sch', 'b.xml')

if __name__ == '__main__':
    main()

Here's the a.sch:

<?xml version="1.0" encoding="utf-8"?>

<schema xmlns="http://purl.oclc.org/dsdl/schematron" schemaVersion="1.0" xml:lang="en" >
    <title>Different behavior of libxml2 C API vs lxml Python regarding value-of select in assert message</title>
    <ns prefix="test" uri="test"/>

    <pattern id="a">
        <rule context="test:b">
            <assert test="count(test:c) = 3">There's only <value-of select="count(test:c)"/> c element(s), it is mandatory to have 3.</assert>
        </rule>
    </pattern>
</schema>

Here's the b.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<?valbuddy_schematron a.sch?>
<a xmlns="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <b>
        <c>word 1</c>
        <c>word 2</c>
    </b>
</a>

Here's the command line using the libxml2 C API (replace files path with your path):

xmllint --schematron ~/svn/r-oltcms/Config/a.sch ~/svn/r-oltcms/Config/b.xml

Here's a portion of the results, we can see that we don't get the value-of select in the assert message.

> /*/* line 4: There's only  c element(s), it is mandatory to have 3.
> /home/oltcms/svn/r-oltcms/Config/b.xml fails to validate

Here's a portion of the result of the python script, we can see that we get the value-of select in the assert message.

> <svrl:failed-assert test="count(test:c) = 3"
> location="/*[local-name()='a' and
> namespace-uri()='test']/*[local-name()='b' and
> namespace-uri()='test']">
>     <svrl:text>There's only 2 c element(s), it is mandatory to have 3.</svrl:text> </svrl:failed-assert>

So, is there a way to get these in the assert message using the libxml2 C API? Any explanation is welcome.

Thanks,

Michel

I think that libxml2 only implements an early Schematron version , probably 1.5 or 1.6 which don't support value-of in assert . The Python bindings to libxml2 's Schematron validator are in lxml.etree.Schematron . But lxml also provides lxml.isoschematron.Schematron which seems to support a newer Schematron version. This validator isn't based on libxml2 directly but on XSLT transforms. So there's probably no way to get the values from a value-of in an assert using libxml2 's C API or xmllint , but you could try to put value-of in a diagnostic .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM