【问题标题】:ISO schematron could not validate processing instructions in XML documentISO schematron 无法验证 XML 文档中的处理指令
【发布时间】:2012-10-29 10:18:49
【问题描述】:

需求说明:我们的需求是在输入的xml文档中寻找目标为PubTbl且具有伪属性@rth的处理指令。这些处理指令特定于 Arbortext Editor,它们以表格形式呈现在整个 XML 文档中。

<?PubTbl row rht="0.76in"?>

我们注意到,在我们的 xml 文档中的处理指令中,我们的 ISO Schematron 架构(如下所述)没有被触发。

  • ISO Schematron 不验证处理指令吗?
  • 如果 ISO Schematron 验证处理指令,是否有任何 设置/参数更改我需要注意吗?

ISO Schematron 架构

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron" id="vert-space-tables_schema"
    queryBinding="xslt2" schemaVersion="iso">
    <title>Forcing vertical space in content within tables</title>
    <pattern id="vert-space-tables_pattern">
        <title>Forcing vertical space in content within tables</title>
        <rule id="vert-space-tables_processing-inst_rule" context="processing-instruction('PubTbl')"
            abstract="false">
            <report test="contains(.,'rht=')"> 
                The table have got processing instructions you are looking altered to modify
                pagination. </report>
        </rule>
    </pattern>
</schema>

我正在使用附加的“ant-schematron-2010-04-14.jar”zip 文件中的 ISO schematron 样式表,使用 ant 任务

   <taskdef name="schematron" classname="com.schematron.ant.SchematronTask"
        classpath="${lib}/ant-schematron-2010-04-14.jar; ${lib}/resolver.jar"/>

<schematron schema="${schema}/vert-space-tables/vert-space-tables.sch" failonerror="false"
            queryLanguageBinding="xslt2" format="svrl" OutputDir="${dist}/vert-space-tables"
            outputFilename="fail.xml" debugMode="true" failOnError="false" diagnose="true" classpathref="saxon-loc">
            <fileset dir="${xml}/vert-space-tables" includes="Forcing_vertical_space_in_content_within_tables-fail.xml"/>            
            </schematron>

“debug.xslt” - 还附加了从 ISO schematron 生成并针对 xml 文档进行验证的 XSL 样式表。

在 debug.xslt 中(在文件底部),我注意到 apply-templates 只处理元素节点,它永远不会处理处理指令,这是为什么呢?

<xsl:template match="@*|node()" priority="-2" mode="M1">
              <xsl:apply-templates select="*****" mode="M1"/>
           </xsl:template>

debug.xslt 内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:saxon="http://saxon.sf.net/"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:schold="http://www.ascc.net/xml/schematron"
                xmlns:iso="http://purl.oclc.org/dsdl/schematron"
                xmlns:xhtml="http://www.w3.org/1999/xhtml"
                version="2.0"><!--Implementers: please note that overriding process-prolog or process-root is 
    the preferred method for meta-stylesheets to use where possible. -->
<xsl:param name="archiveDirParameter"/>
   <xsl:param name="archiveNameParameter"/>
   <xsl:param name="fileNameParameter"/>
   <xsl:param name="fileDirParameter"/>
   <xsl:variable name="document-uri">
      <xsl:value-of select="document-uri(/)"/>
   </xsl:variable>

   <!--PHASES-->


<!--PROLOG-->
<xsl:output xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
               method="xml"
               omit-xml-declaration="no"
               standalone="yes"
               indent="yes"/>

   <!--XSD TYPES FOR XSLT2-->


<!--KEYS AND FUNCTIONS-->


<!--DEFAULT RULES-->


<!--MODE: SCHEMATRON-SELECT-FULL-PATH-->
<!--This mode can be used to generate an ugly though full XPath for locators-->
<xsl:template match="*" mode="schematron-select-full-path">
      <xsl:apply-templates select="." mode="schematron-get-full-path"/>
   </xsl:template>

   <!--MODE: SCHEMATRON-FULL-PATH-->
<!--This mode can be used to generate an ugly though full XPath for locators-->
<xsl:template match="*" mode="schematron-get-full-path">
      <xsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
      <xsl:text>/</xsl:text>
      <xsl:choose>
         <xsl:when test="namespace-uri()=''">
            <xsl:value-of select="name()"/>
         </xsl:when>
         <xsl:otherwise>
            <xsl:text>*:</xsl:text>
            <xsl:value-of select="local-name()"/>
            <xsl:text>[namespace-uri()='</xsl:text>
            <xsl:value-of select="namespace-uri()"/>
            <xsl:text>']</xsl:text>
         </xsl:otherwise>
      </xsl:choose>
      <xsl:variable name="preceding"
                    select="count(preceding-sibling::*[local-name()=local-name(current())                                   and namespace-uri() = namespace-uri(current())])"/>
      <xsl:text>[</xsl:text>
      <xsl:value-of select="1+ $preceding"/>
      <xsl:text>]</xsl:text>
   </xsl:template>
   <xsl:template match="@*" mode="schematron-get-full-path">
      <xsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
      <xsl:text>/</xsl:text>
      <xsl:choose>
         <xsl:when test="namespace-uri()=''">@<xsl:value-of select="name()"/>
         </xsl:when>
         <xsl:otherwise>
            <xsl:text>@*[local-name()='</xsl:text>
            <xsl:value-of select="local-name()"/>
            <xsl:text>' and namespace-uri()='</xsl:text>
            <xsl:value-of select="namespace-uri()"/>
            <xsl:text>']</xsl:text>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <!--MODE: SCHEMATRON-FULL-PATH-2-->
<!--This mode can be used to generate prefixed XPath for humans-->
<xsl:template match="node() | @*" mode="schematron-get-full-path-2">
      <xsl:for-each select="ancestor-or-self::*">
         <xsl:text>/</xsl:text>
         <xsl:value-of select="name(.)"/>
         <xsl:if test="preceding-sibling::*[name(.)=name(current())]">
            <xsl:text>[</xsl:text>
            <xsl:value-of select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
            <xsl:text>]</xsl:text>
         </xsl:if>
      </xsl:for-each>
      <xsl:if test="not(self::*)">
         <xsl:text/>/@<xsl:value-of select="name(.)"/>
      </xsl:if>
   </xsl:template>
   <!--MODE: SCHEMATRON-FULL-PATH-3-->
<!--This mode can be used to generate prefixed XPath for humans 
    (Top-level element has index)-->
<xsl:template match="node() | @*" mode="schematron-get-full-path-3">
      <xsl:for-each select="ancestor-or-self::*">
         <xsl:text>/</xsl:text>
         <xsl:value-of select="name(.)"/>
         <xsl:if test="parent::*">
            <xsl:text>[</xsl:text>
            <xsl:value-of select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
            <xsl:text>]</xsl:text>
         </xsl:if>
      </xsl:for-each>
      <xsl:if test="not(self::*)">
         <xsl:text/>/@<xsl:value-of select="name(.)"/>
      </xsl:if>
   </xsl:template>

   <!--MODE: GENERATE-ID-FROM-PATH -->
<xsl:template match="/" mode="generate-id-from-path"/>
   <xsl:template match="text()" mode="generate-id-from-path">
      <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
      <xsl:value-of select="concat('.text-', 1+count(preceding-sibling::text()), '-')"/>
   </xsl:template>
   <xsl:template match="comment()" mode="generate-id-from-path">
      <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
      <xsl:value-of select="concat('.comment-', 1+count(preceding-sibling::comment()), '-')"/>
   </xsl:template>
   <xsl:template match="processing-instruction()" mode="generate-id-from-path">
      <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
      <xsl:value-of select="concat('.processing-instruction-', 1+count(preceding-sibling::processing-instruction()), '-')"/>
   </xsl:template>
   <xsl:template match="@*" mode="generate-id-from-path">
      <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
      <xsl:value-of select="concat('.@', name())"/>
   </xsl:template>
   <xsl:template match="*" mode="generate-id-from-path" priority="-0.5">
      <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
      <xsl:text>.</xsl:text>
      <xsl:value-of select="concat('.',name(),'-',1+count(preceding-sibling::*[name()=name(current())]),'-')"/>
   </xsl:template>

   <!--MODE: GENERATE-ID-2 -->
<xsl:template match="/" mode="generate-id-2">U</xsl:template>
   <xsl:template match="*" mode="generate-id-2" priority="2">
      <xsl:text>U</xsl:text>
      <xsl:number level="multiple" count="*"/>
   </xsl:template>
   <xsl:template match="node()" mode="generate-id-2">
      <xsl:text>U.</xsl:text>
      <xsl:number level="multiple" count="*"/>
      <xsl:text>n</xsl:text>
      <xsl:number count="node()"/>
   </xsl:template>
   <xsl:template match="@*" mode="generate-id-2">
      <xsl:text>U.</xsl:text>
      <xsl:number level="multiple" count="*"/>
      <xsl:text>_</xsl:text>
      <xsl:value-of select="string-length(local-name(.))"/>
      <xsl:text>_</xsl:text>
      <xsl:value-of select="translate(name(),':','.')"/>
   </xsl:template>
   <!--Strip characters--><xsl:template match="text()" priority="-1"/>

   <!--SCHEMA SETUP-->
<xsl:template match="/">
      <svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
                              title="Forcing vertical space in content within tables"
                              schemaVersion="iso">
         <xsl:comment>
            <xsl:value-of select="$archiveDirParameter"/>   
         <xsl:value-of select="$archiveNameParameter"/>  
         <xsl:value-of select="$fileNameParameter"/>  
         <xsl:value-of select="$fileDirParameter"/>
         </xsl:comment>
         <svrl:active-pattern>
            <xsl:attribute name="document">
               <xsl:value-of select="document-uri(/)"/>
            </xsl:attribute>
            <xsl:attribute name="id">vert-space-tables_pattern</xsl:attribute>
            <xsl:attribute name="name">Forcing vertical space in content within tables</xsl:attribute>
            <xsl:apply-templates/>
         </svrl:active-pattern>
         <xsl:apply-templates select="/" mode="M1"/>
      </svrl:schematron-output>
   </xsl:template>

   <!--SCHEMATRON PATTERNS-->
<svrl:text xmlns:svrl="http://purl.oclc.org/dsdl/svrl">Forcing vertical space in content within tables</svrl:text>

   <!--PATTERN vert-space-tables_patternForcing vertical space in content within tables-->
<svrl:text xmlns:svrl="http://purl.oclc.org/dsdl/svrl">Forcing vertical space in content within tables</svrl:text>

      <!--RULE vert-space-tables_processing-inst_rule-->
<xsl:template match="processing-instruction('PubTbl')" priority="1000" mode="M1">
      <svrl:fired-rule xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
                       context="processing-instruction('PubTbl')"
                       id="vert-space-tables_processing-inst_rule"/>

            <!--REPORT -->
<xsl:if test="contains(., 'breakpenalty=&#34;-10000&#34;') or contains(., 'breakpenalty=&#34;2000&#34;') or contains(.,'rht=')">
         <svrl:successful-report xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
                                 test="contains(., 'breakpenalty=&#34;-10000&#34;') or contains(., 'breakpenalty=&#34;2000&#34;') or contains(.,'rht=')">
            <xsl:attribute name="location">
               <xsl:apply-templates select="." mode="schematron-select-full-path"/>
            </xsl:attribute>
            <svrl:text> 
                The table have got processing instructions you are looking altered to modify
                pagination. </svrl:text>
         </svrl:successful-report>
      </xsl:if>
      <xsl:apply-templates select="*" mode="M1"/>
   </xsl:template>
   <xsl:template match="text()" priority="-1" mode="M1"/>
   <xsl:template match="@*|node()" priority="-2" mode="M1">
      <xsl:apply-templates select="*" mode="M1"/>
   </xsl:template>
</xsl:stylesheet>

感谢和问候, 苏雷什。

【问题讨论】:

  • 你说你正在尝试匹配@rth,但测试是针对“rht="?当我用测试和 PI 对你的 schematron 进行测试时,它工作得很好。
  • 澄清了一点要求。
  • @nine9ths:感谢您的回复。您是否对处理指令进行了任何设置修改以获得识别?只是为了更新我的发现,xml 文档在 Oxygen XML 编辑器中触发了处理指令规则,但是当通过 ant“ant-schematron-2010-04-14.jar”传递相同的文档时,在 svrl 输出中我注意到这些处理-文档中的指令不会被触发。下面显示的是我使用时的 svrl 输出
  • {purl.oclc.org/dsdl/svrl" ... title="强制垂直空间在表中的内容中" schemaVersion="iso"> }

标签: xml validation xslt schematron


【解决方案1】:

当我运行这个 schematron 文件(从上面复制)时,我无法重现这个问题:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron" id="vert-space-tables_schema"
  queryBinding="xslt2" schemaVersion="iso">
  <title>Forcing vertical space in content within tables</title>
  <pattern id="vert-space-tables_pattern">
    <title>Forcing vertical space in content within tables</title>
    <rule id="vert-space-tables_processing-inst_rule" context="processing-instruction('PubTbl')"
      abstract="false">
      <report test="contains(.,'rht=')"> 
        The table have got processing instructions you are looking altered to modify
        pagination. </report>
    </rule>
  </pattern>
</schema>

反对这个xml:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <?PubTbl row rht="0.76in"?>  
</root>

使用 Oxygen 14 的 schematron 实现,我收到以下消息:

Warning: unrecognized element svrl:schematron-output

当我下载 http://schematron.googlecode.com/files/ant-schematron-2010-04-14.jar 并从中使用 iso_svrl_for_xslt2.xsl 来编译 schematron,然后针对示例 xml 运行它时,我得到以下 svrl:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
                        xmlns:xs="http://www.w3.org/2001/XMLSchema"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                        xmlns:saxon="http://saxon.sf.net/"
                        xmlns:schold="http://www.ascc.net/xml/schematron"
                        xmlns:iso="http://purl.oclc.org/dsdl/schematron"
                        xmlns:xhtml="http://www.w3.org/1999/xhtml"
                        title="Forcing vertical space in content within tables"
                        schemaVersion="iso"><!--   
           
           
         --><svrl:active-pattern document="file:/Users/nunes/Desktop/tmp/test.xml"
                        id="vert-space-tables_pattern"
                        name="Forcing vertical space in content within tables"/>
</svrl:schematron-output>

当我从同一个 jar 中运行 iso_schematron_message.xsl 时,我也收到了消息:

Warning: unrecognized element svrl:schematron-output

当我将你的 debug.xslt 与我使用指定 jar 中的样式表生成的 xsl 进行比较时(在它们都运行 Oxygen 的 tidy 以标准化空白之后)我看到了这些差异:

--- debug.xslt  2012-11-10 00:19:39.000000000 -0800
+++ iso.xsl     2012-11-10 00:19:14.000000000 -0800
@@ -310 +310 @@
-      test="contains(., 'breakpenalty=&#34;-10000&#34;') or contains(., 'breakpenalty=&#34;2000&#34;') or contains(.,'rht=')">
+      test="contains(.,'rht=')">
@@ -312 +312 @@
-        test="contains(., 'breakpenalty=&#34;-10000&#34;') or contains(., 'breakpenalty=&#34;2000&#34;') or contains(.,'rht=')"
+        test="contains(.,'rht=')"

您确定您使用的是上面粘贴的 schematron 并使用正确的样式表对其进行解析吗?

【讨论】:

  • 啊没有看到它在 Oxygen 中工作但在 ant 中失败,我怀疑 ant 是你的问题而不是 schematron。抱歉,我帮不上什么忙:(
  • 您好,九十九,感谢您的帮助。你一直在努力帮助我。
  • 是的,我上次错误地添加了不同的 debug.xslt。很抱歉造成混乱。
  • 创建了一个 xml 文档&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;?oxygen SCHSchema="test-processing-instruction.sch" type="xml"?&gt; &lt;root&gt; &lt;?PubTbl row rht="0.76in"?&gt; &lt;/root&gt;
    如您所见,我在 xml 文档中添加了一个特定于氧气的处理指令,当验证 xml 文档时,处理指令相关的消息在消息框中显示如下 **具有文本值为 rht 的处理指令,这是不好的。 (contains(.,'rht=')) [report] **,从中我们可以得出结论,处理指令在 Oxygen Editor 中被识别。
  • 我终于找到了解决办法。这是“ant-schematron-2010-04-14.jar”中存在的 iso_schematron_skeleton_for_saxon.xsl 中的一个错误。样式表参数“only-child-elements”的值应该为“false”,但是当schematron模式规则上下文属性有处理指令或注释时,该值变为“true”,这导致了问题&lt;xsl:param name="only-child-elements"&gt; &lt;xsl:choose&gt; &lt;xsl:when test="//iso:rule[contains(@context,'(')]"&gt;true&lt;/xsl:when&gt; &lt;xsl:otherwise&gt;false&lt;/xsl:otherwise&gt; &lt;/xsl:choose&gt; &lt;/xsl:param&gt;
猜你喜欢
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多