xslt验证/转换在oXygen中工作,但不能与lxml python脚本一起工作?

时间:2016-06-06 20:59:12

标签: xslt lxml

我已经包含了用于产生错误的文件。

这些工作在oXygen; python lxml脚本不起作用。

更具体地说,转换有效,但验证错误无法正常工作。 (例如,如果id更改为ids。)

toy.xml

<?xml version="1.0" encoding="UTF-8"?>
 <?xml-model href="file:/randng.rnc" type="application/relax-ng-compact-syntax"?>
 <?xml-model href="file:/toytest.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<report>
<title>Variant calling and annotation for Dr.Smith</title>
<date>July 1,1985</date>
<analysis id="NGS">
    <method id="QC"></method>
    <method id="GATK"></method>
</analysis>
<analysis id="genome_alignment">
    <method id="bowtie2"></method>
</analysis>     
</report>

test.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:template match="/">
        <html>
            <head>
                <h2>Report for Dr Zoidberg</h2>
              <div><xsl:value-of  select="current-date()"/></div>
                <div><xsl:apply-templates select="/report/date"></xsl:apply-templates></div>
            </head>
            <body>
                <h2>Table of Contents</h2>
                <ul><xsl:apply-templates select="//analysis" mode="toc"/></ul>

                <h2>Analysis</h2>
                <ul><xsl:apply-templates select="//analysis" mode="analysis"/></ul>   
                <!-- <xsl:apply-templates select="/report/analysis/method"/>-->

                <h2>Citations</h2>
                <ul><xsl:apply-templates select="//method" mode="cite"></xsl:apply-templates></ul>

            </body>
        </html>
    </xsl:template>

    <!-- list analysis    -->
    <xsl:template match="analysis" mode="analysis">
           <li id="{@id}"> 
               <xsl:apply-templates select="@id"/> 
                <ul><xsl:apply-templates select="/analysis/method"></xsl:apply-templates>
                    <xsl:apply-templates select="method"/>           
                </ul>
           </li>
    </xsl:template>
    <!-- list methods    -->
    <xsl:template match="method">
            <li>
                <xsl:apply-templates select="@id"/>
                <!--citation-->
                <xsl:for-each select="document('contentconfig.xml')/cfg/analysis/method[@id=current()/@id]/citation">
                    <sup>
                        <a href="#cite{count(preceding::citation) + 1}">
                            <xsl:value-of select="count(preceding::citation) + 1"/>
                        </a>
                        </sup>
                </xsl:for-each>       
            </li>
    </xsl:template>

    <!--TOC based on analysis -->
    <xsl:template match="analysis" mode="toc">
        <li>
            <a href="#{@id}">
            <xsl:apply-templates select="@id"/>
            </a>
        </li>
    </xsl:template>

    <!--Citations    -->
    <xsl:template match="method" mode="cite">

            <xsl:for-each select="document('contentconfig.xml')/cfg/analysis/method[@id=current()/@id]/citation">
                <li>
                    <cite id="cite{count(preceding::citation) + 1}">
                    [<xsl:value-of select="count(preceding::citation) + 1"/>]
                    <xsl:apply-templates/>
                    </cite>
                </li>
            </xsl:for-each>

    </xsl:template>

</xsl:stylesheet>

randng.rng

<!--<?xml version="1.0" encoding="UTF-8"?>-->
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <ref name="report"/>
  </start>
  <define name="report">
    <element name="report">
      <optional>
        <ref name="title"/>
      </optional>
      <optional>
        <ref name="date"/>
      </optional>
      <oneOrMore>
        <ref name="analysis"/>
      </oneOrMore>
    </element>
  </define>
  <define name="title">
    <element name="title">
      <text/>
    </element>
  </define>
  <define name="date">
    <element name="date">
      <text/>
    </element>
  </define>
  <define name="analysis">
    <element name="analysis">
      <attribute name="id"/>
      <oneOrMore>
        <ref name="method"/>
      </oneOrMore>
    </element>
  </define>
  <define name="method">
    <element name="method">
      <attribute name="id"/>
      <text/>
    </element>
  </define>
</grammar>

toytest.sch

<schema xmlns="http://purl.oclc.org/dsdl/schematron" >
    <pattern id="sum_equals_100_percent">
    <title>Sum equals 100%.</title>
    <rule context="Total">
    <assert test="sum(//Percent)=100">Sum is not 100%.</assert>
    </rule>
    </pattern>
    </schema>

但是,当我尝试使用python lxml时,我得到一个RELAXNG_ERR_ELEMNAME。 这是python script

 import shlex, subprocess
 from lxml import isoschematron
 from lxml import etree

# _VALIDATE_
# parse sch,xml,relaxNG
parser_xml = etree.XMLParser()
sch_doc = etree.parse('toy.sch')
schematron =  isoschematron.Schematron(sch_doc, store_report = True)

#xml_doc = etree.parse('toy.xsl', parser_xml)
xml_doc = etree.parse('toy.xsl')

##compact to relaxNG
#pytrang randng.rnc randng.rng 
randNG_doc = etree.parse('randng.rng')
relaxng = etree.RelaxNG(randNG_doc)

# validate against schematron
validationResult = schematron.validate(xml_doc)
print '--------------------'
print validationResult

# validate against relaxNG
try:
    validateRelaxng =  relaxng.assert_(xml_doc)
print 'relaxNG worked'
except AssertionError as e:
error =   relaxng.error_log.last_error
print relaxng.error_log
print error.type_name
if error.type_name == 'RELAXNG_ERR_ATTRVALID':
    print 'invalid attribute'
 #       RELAXNG_ERR_ELEMNAME

 # _TRANSFORM_ 
 #just run it from shell
 cmd = "java -cp /usr/share /java/saxonb.jar  net.sf.saxon.Transform -xsl:test2.xsl -s:toy.xml -o:toy6.html"
 args = shlex.split(cmd)
 #subprocess.Popen(args)

转换有效,验证不会产生正确的错误。

我最后只是使用命令行调用进行转换。 sch和rng文件xslt_1.0是否兼容?为什么我不能让简单的脚本工作,还有什么其他问题呢?

最好的

1 个答案:

答案 0 :(得分:0)

无意中尝试解析样式表......应该从元素错误中找出答案。相反,应该只解析xml doc,然后对其进行验证。