我的要求是: “不允许列入黑名单的单词出现在特定的XML标记中”。
我正在尝试使用XML正则表达式模式的xs:restriction。
我引用了以下链接:Restrict word list in XML schema。
例如:BLACKLISTED WORDS: byte,bing,ding
问题:如果单词以相同的字母开头( b ), 会传递 bing < / em> 条件和反之亦然。
我可以使用AND运算符吗?还有其他更简单的方法吗?
提前致谢!!
答案 0 :(得分:2)
无论你做了什么,你都错了;我们无法通过阅读您引用的长线程来确定您所做的事情,因此您必须告诉我们。告诉我们您要实现的目标可能也是一个好主意,因为可能有更好的方法。除了其他任何事情,自2009年以来世界已经发展,您可能可以使用XSD 1.1。
答案 1 :(得分:0)
在原始问题中,它相对简单,将每个禁止的词翻译成允许的模式列表。但在这种情况下,生成的列表会发生冲突,因此在生成完整的模式列表时,您必须立即考虑所有单词:
b
或d
b
开头,下一个字符不是y
或i
by
开头,下一个字符不是t
byt
开头,下一个字符不是e
byte
开头并且至少还有一个字符byt
,by
或b
d
开头,下一个字符不是i
bi
或di
开头,下一个字符不是n
bin
或din
开头,下一个字符不是g
bing
或ding
开头并且至少还有一个字符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所说,在此期间出现了更好的解决方案。
答案 2 :(得分:0)
在XSD 1.1中,您可以这样做:
<xs:assert test="not(tokenize($value, '\s+') = ('byte', 'bing', 'ding'))"/>
Saxon和Xerces目前支持XSD 1.1。
答案 3 :(得分:0)
根据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 非常重要,否则将失败。
答案 4 :(得分:0)
如果可能的话,XSD 1.1可能就是这样。其他答案已经涵盖了这一点,我倾向于相信它们: - )
在XSD 1.0中,叠加否定的唯一方法是使用否定集重复限制条件(xs:pattern
),每个(正)断言一次,例如:
<xs:pattern value="([^(byte)]" />
<xs:pattern value="([^(bing)])" />
<xs:pattern value="([^(ding)])" />
您还可以进一步指定每个单词,每个字母等的大小写。
只要你否定整个事情你就是“黑名单”,你应该能够用相对可读的模式来构建它。