Regex CALS表模型中列宽一致单位的xpath断言

Regex CALS表模型中列宽一致单位的xpath断言,regex,xslt,xpath,docbook,Regex,Xslt,Xpath,Docbook,我正在使用基于XMLSchema1.1的标记语言,这将是DocBook词汇表中非常有限的一个子集。它包含CALS表格模型。表的列规格在colspec/@colwidth属性中具有列宽。表定义中允许一系列colspec元素。列的宽度可以用多种单位定义,例如。g、 15mm或10*(后者为比例宽度) 我想编写一个xs:assertion,用于检查所有colspec的单位是否具有相同的列宽单位。例如: 序列10mm、20mm、30mm的结果应为真。只有一个绝对单位(mm) 序列10mm、2cm、30

我正在使用基于XMLSchema1.1的标记语言,这将是DocBook词汇表中非常有限的一个子集。它包含CALS表格模型。表的列规格在colspec/@colwidth属性中具有列宽。表定义中允许一系列colspec元素。列的宽度可以用多种单位定义,例如。g、 15mm或10*(后者为比例宽度)

我想编写一个xs:assertion,用于检查所有colspec的单位是否具有相同的列宽单位。例如:

  • 序列10mm、20mm、30mm的结果应为真。只有一个绝对单位(mm)
  • 序列10mm、2cm、30mm的结果应为假。有两个绝对但不同的单位(毫米、厘米)
  • 序列10mm、2*、30mm的结果应为假。有两个单位(mm,*),因此绝对和比例是混合的。这比上面两个不同但绝对的单位更糟糕
我不知道如何做到这一点。如果我可以标记列宽值,那么类似count的值(不同的值(对于@colwidth中的$w)返回的单位是($w))(等式1

但是如何编写函数-unit-of()?XPath函数fn:tokenize需要一个模式,在本例中似乎不可用

有什么想法吗


Frank Steimke

解决方案:根据michael.hor257k的建议,table/tgroup元素中的这个断言有效:

<xs:assert test="
        count(distinct-values(for $unit in sd:colspec/@colwidth
        return
           translate($unit, '0123456789\.', ''))) eq 1"/>

colwidth属性的类型是(im my XSD Schema)对xs:token的限制,regex=\d+(.\d+)(*|[c|m]m|in)

fn:translate函数将数字和小数分隔符从@colwidth值映射到空字符串,这样只剩下单位(10mm变为mm,10*变为*)。如果在不同的单元序列中没有一个单元,则断言将失败

谢谢,
Frank

表达断言的另一种方式可能更有效(当然取决于实现)是

使用Saxon,使用“every…”编写断言的一个优点是,当断言不满足时,诊断程序会告诉您哪一个$c是罪魁祸首


至于这个问题,您可以将
f:unit($x)
简单地实现为
translate($x,'0123456789.','')
,或者如果您愿意,可以实现为
replace($x,'0-9\.]','')

这个单位不是除了数字以外的所有字符(可能还有十进制分隔符)?True。这确实是解决方案:我可以使用fn:translate函数过滤掉数字和小数分隔符,这样只剩下字符。非常感谢你的建议。
every $c in xx/@colwidth satisfies f:unit($c) eq f:unit(xx[1]/@colwidth)