我的要求是:“不允许列入黑名单的单词出现在特定的 XML 标记中”。
我正在尝试使用 XML 正则表达式模式的 xs:restriction。
我引用了以下链接:Restrict word list in XML schema。
例如:列入黑名单的词:字节、bing、ding
问题:如果单词以相同的字母 ( b ) 开头,则字节通过bing条件,反之亦然。
我可以使用 AND 运算符吗?还有其他更简单的方法吗?
提前致谢 !!
我的要求是:“不允许列入黑名单的单词出现在特定的 XML 标记中”。
我正在尝试使用 XML 正则表达式模式的 xs:restriction。
我引用了以下链接:Restrict word list in XML schema。
例如:列入黑名单的词:字节、bing、ding
问题:如果单词以相同的字母 ( b ) 开头,则字节通过bing条件,反之亦然。
我可以使用 AND 运算符吗?还有其他更简单的方法吗?
提前致谢 !!
不管你做了什么,你都错了;而且我们无法通过阅读您引用的那个长线程来真正弄清楚您做了什么,所以您必须告诉我们。告诉我们您想要实现的目标可能也是一个好主意,因为可能有更好的方法。撇开别的不说,世界自 2009 年以来一直在发展,您或许可以使用 XSD 1.1。
在 XSD 1.1 中,您可以这样做:
<xs:assert test="not(tokenize($value, '\s+') = ('byte', 'bing', 'ding'))"/>
Saxon 和 Xerces 目前支持 XSD 1.1。
在最初的问题中,它相对简单,将每个禁用词转换为允许模式列表。但是在这种情况下,结果列表会发生冲突,因此您必须在生成完整的模式列表时同时考虑所有单词:
b
或以外的任何内容开头d
b
, 下一个字符 noty
或i
by
,下一个字符不是t
byt
,下一个字符不是e
byte
AND 开头至少还有一个字符byt
,by
或b
d
,下一个字符不是i
bi
以or开头di
,下一个字符不是n
bin
以or开头din
,下一个字符不是g
bing
or开头ding
AND 至少还有一个字符bin
, bi
, b
, din
,di
或d
结果:
<xsd:pattern value=
"([^bd].*|b[^yi].*|by[^t].*|byt[^e].*|byte.+|b(yt?)?|d[^i].*|[bd]i[^n].*|[bd]in[^g].*|[bd]ing.+|[bd](in?)?)"
/>
可能可以编写一个程序来生成正则表达式,但这看起来需要大量的工作。自从我写了对原始问题的回答以来,我还没有研究过这个问题;正如@MichaelKay 所说,我希望同时出现更好的解决方案。
根据 Michael Kay 的回答,我已经使用 XSD 1.1 实现了逻辑。(我不得不将$value更改为@name)
步骤: 1. 将以下代码与最新的 Xerces 1.1 实现 jar 文件一起使用。
<xs:element name="random-element">
<xs:complexType>
<xs:attribute name="name" use="required" type="xs:string" />
<xs:attribute name="value" use="optional" type="xs:string" />
<xs:assert test="not(tokenize(@name, '\s+') = ('byte', 'bing', 'ding'))"/>
</xs:complexType>
</xs:element>
3. 使用以下代码验证:
final SchemaFactory schemaFactory = SchemaFactory.newInstance(Constants.W3C_XML_SCHEMA11_NS_URI);
final Schema schema = schemaFactory.newSchema(schemaFile);
final Validator validator = schema.newValidator();
validator.validate(xmlFile);
常量W3C_XML_SCHEMA11_NS_URI非常重要,否则会失败。
如果可能的话,XSD 1.1 可能是最好的选择。其他答案已经涵盖了这一点,我倾向于相信他们:-)
在 XSD 1.0 中,堆叠否定的唯一方法是xs:pattern
使用否定集重复限制条件 ( ),每个(正)断言一个,例如:
<xs:pattern value="([^(byte)]" />
<xs:pattern value="([^(bing)])" />
<xs:pattern value="([^(ding)])" />
您还可以进一步指定每个单词、每个字母等的大小写。
只要你否定你被“列入黑名单”的整个事情,你就应该能够用相对易读的模式来构建它。