RelaxNG 中嵌入的 Schematron 断言规则产生未声明的命名空间前缀错误
Schematron Assert rule embedded in RelaxNG produces undeclared namespace prefix error
示例代码
考虑以下有点做作的 XML 实例:
file.xml
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<table aid:trows="3" aid:tcols="2">
<Cell>header column 1</Cell>
<Cell>header column 2</Cell>
<Cell>row 1 column 1</Cell>
<Cell>row 1 column 2</Cell>
<Cell>row 2 column 1</Cell>
<Cell>row 2 column 2</Cell>
</table>
</section>
它使用以下 Relax NG 模式成功验证:
schema.rng
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/"
xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<start>
<ref name="section"/>
</start>
<define name="section">
<element name="section">
<ref name="table"/>
</element>
</define>
<define name="table">
<sch:pattern name="Test attributes aid:rows and aid:tcols when multiplied equal count of Cell elements">
<sch:rule context="table">
<sch:assert test="count(./Cell) = 6">Count of Cell elements does not match specified @aid:rows and @aid:tcols.</sch:assert>
</sch:rule>
</sch:pattern>
<element name="table">
<attribute name="aid:trows">
<data type="integer"/>
</attribute>
<attribute name="aid:tcols">
<data type="integer"/>
</attribute>
<oneOrMore>
<element name="Cell">
<text/>
</element>
</oneOrMore>
</element>
</define>
</grammar>
注:schema.rng
中的内嵌Schematron规则,即如下部分:
<sch:pattern name="Test attributes aid:rows and aid:tcols when multiplied equal count of Cell elements">
<sch:rule context="table">
<sch:assert test="count(./Cell) = 6">Count of Cell elements does not match specified @aid:rows and @aid:tcols.</sch:assert>
</sch:rule>
</sch:pattern>
这条规则assert
的Cell
个元素节点的数量必须等于6
:
我想做什么?
我试图避免硬编码 Cell
元素的计数必须在当前在 Schematron 规则中定义的 XPath count
函数中。即这部分 (在下面再次显示) 说明 Cell
元素的数量必须是六个:
<sch:assert test="count(./Cell) = 6">...</sch:assert>
^
我想做的是通过乘以与 table
关联的 aid:trows
和 aid:tcols
属性的值来推断 Cell
元素的计数必须是多少元素。即从下面再次显示的 file.xml 中的这些属性推断它:
<table aid:trows="3" aid:tcols="2">
^ ^
...
</table>
我尝试了什么...
我尝试重新定义 Schematron 规则中的 XPath count
函数,如下所示。
<sch:assert test="count(./Cell) = @aid:trows * @aid:tcols">...</sch:assert>
但是,尝试验证 file.xml 会产生以下错误 (顺便说一句。我正在使用 Oxygen XML 编辑器):
Failed to compile stylesheet. 1 error detected.
Undeclared namespace prefix {aid}
Got a fatal error trying to create a transformer from the stylesheet!
aid
命名空间前缀似乎有问题!
我在这里误解了什么?我该如何解决这个问题?
什么有效?
为了确定它是否与 aid
命名空间前缀相关,我尝试了以下确实有效的方法:
在file.xml中我省略了关联的aid:trows
和aid:tcol
属性中的aid
前缀table
如下所示:
...
<table trows="3" tcols="2">
...
</table>
然后重新定义:
- Schematron 规则中的 XPath
count
函数为 count(./Cell) = @trows * @tcols
- 并将
table
的属性定义为 trows
和 tcols
,即省略了 aid:
前缀。
基本上我将 table
的命名模式重新定义为以下内容:
...
<define name="table">
<sch:pattern name="Test attributes aid:rows and aid:tcols when multiplied equal count of Cell elements">
<sch:rule context="table">
<!-- change below -->
<sch:assert test="count(./Cell) = @trows * @tcols">Count of Cell elements does not match specified @aid:rows and @aid:tcols.</sch:assert>
</sch:rule>
</sch:pattern>
<element name="table">
<!-- change below -->
<attribute name="trows">
<data type="integer"/>
</attribute>
<!-- change below -->
<attribute name="tcols">
<data type="integer"/>
</attribute>
<oneOrMore>
<element name="Cell">
<text/>
</element>
</oneOrMore>
</element>
</define>
...
这里有一些选项:
Schemetron 断言测试中使用的名称空间前缀必须使用 Schematron ns
元素声明。添加以下内容作为 RelaxNG 架构中 <grammar>
中的第一个子项:
<sch:ns prefix="aid" uri="http://ns.adobe.com/AdobeInDesign/4.0/"/>
或者,您可以使用 xPath namespace-uri()
函数在断言测试中断言属性的名称空间。变化:
@aid:trows
至:
@*:trows[namespace-uri() = 'http://ns.adobe.com/AdobeInDesign/4.0/']
(tcols
也一样)。
或者,如果你很懒,你可以使用 @*:trows
,这将 select trows
任何命名空间的属性。
示例代码
考虑以下有点做作的 XML 实例:
file.xml
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<table aid:trows="3" aid:tcols="2">
<Cell>header column 1</Cell>
<Cell>header column 2</Cell>
<Cell>row 1 column 1</Cell>
<Cell>row 1 column 2</Cell>
<Cell>row 2 column 1</Cell>
<Cell>row 2 column 2</Cell>
</table>
</section>
它使用以下 Relax NG 模式成功验证:
schema.rng
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/"
xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<start>
<ref name="section"/>
</start>
<define name="section">
<element name="section">
<ref name="table"/>
</element>
</define>
<define name="table">
<sch:pattern name="Test attributes aid:rows and aid:tcols when multiplied equal count of Cell elements">
<sch:rule context="table">
<sch:assert test="count(./Cell) = 6">Count of Cell elements does not match specified @aid:rows and @aid:tcols.</sch:assert>
</sch:rule>
</sch:pattern>
<element name="table">
<attribute name="aid:trows">
<data type="integer"/>
</attribute>
<attribute name="aid:tcols">
<data type="integer"/>
</attribute>
<oneOrMore>
<element name="Cell">
<text/>
</element>
</oneOrMore>
</element>
</define>
</grammar>
注:schema.rng
中的内嵌Schematron规则,即如下部分:
<sch:pattern name="Test attributes aid:rows and aid:tcols when multiplied equal count of Cell elements"> <sch:rule context="table"> <sch:assert test="count(./Cell) = 6">Count of Cell elements does not match specified @aid:rows and @aid:tcols.</sch:assert> </sch:rule> </sch:pattern>
这条规则assert
的Cell
个元素节点的数量必须等于6
:
我想做什么?
我试图避免硬编码 Cell
元素的计数必须在当前在 Schematron 规则中定义的 XPath count
函数中。即这部分 (在下面再次显示) 说明 Cell
元素的数量必须是六个:
<sch:assert test="count(./Cell) = 6">...</sch:assert>
^
我想做的是通过乘以与 table
关联的 aid:trows
和 aid:tcols
属性的值来推断 Cell
元素的计数必须是多少元素。即从下面再次显示的 file.xml 中的这些属性推断它:
<table aid:trows="3" aid:tcols="2">
^ ^
...
</table>
我尝试了什么...
我尝试重新定义 Schematron 规则中的 XPath count
函数,如下所示。
<sch:assert test="count(./Cell) = @aid:trows * @aid:tcols">...</sch:assert>
但是,尝试验证 file.xml 会产生以下错误 (顺便说一句。我正在使用 Oxygen XML 编辑器):
Failed to compile stylesheet. 1 error detected. Undeclared namespace prefix {aid} Got a fatal error trying to create a transformer from the stylesheet!
aid
命名空间前缀似乎有问题!
我在这里误解了什么?我该如何解决这个问题?
什么有效?
为了确定它是否与 aid
命名空间前缀相关,我尝试了以下确实有效的方法:
在file.xml中我省略了关联的
aid:trows
和aid:tcol
属性中的aid
前缀table
如下所示:... <table trows="3" tcols="2"> ... </table>
然后重新定义:
- Schematron 规则中的 XPath
count
函数为count(./Cell) = @trows * @tcols
- 并将
table
的属性定义为trows
和tcols
,即省略了aid:
前缀。
基本上我将
table
的命名模式重新定义为以下内容:... <define name="table"> <sch:pattern name="Test attributes aid:rows and aid:tcols when multiplied equal count of Cell elements"> <sch:rule context="table"> <!-- change below --> <sch:assert test="count(./Cell) = @trows * @tcols">Count of Cell elements does not match specified @aid:rows and @aid:tcols.</sch:assert> </sch:rule> </sch:pattern> <element name="table"> <!-- change below --> <attribute name="trows"> <data type="integer"/> </attribute> <!-- change below --> <attribute name="tcols"> <data type="integer"/> </attribute> <oneOrMore> <element name="Cell"> <text/> </element> </oneOrMore> </element> </define> ...
- Schematron 规则中的 XPath
这里有一些选项:
Schemetron 断言测试中使用的名称空间前缀必须使用 Schematron
ns
元素声明。添加以下内容作为 RelaxNG 架构中<grammar>
中的第一个子项:<sch:ns prefix="aid" uri="http://ns.adobe.com/AdobeInDesign/4.0/"/>
或者,您可以使用 xPath
namespace-uri()
函数在断言测试中断言属性的名称空间。变化:@aid:trows
至:
@*:trows[namespace-uri() = 'http://ns.adobe.com/AdobeInDesign/4.0/']
(
tcols
也一样)。或者,如果你很懒,你可以使用
@*:trows
,这将 selecttrows
任何命名空间的属性。