【问题标题】:Blacklist words in XMLXML 中的黑名单词
【发布时间】:2012-06-29 01:07:23
【问题描述】:

我的要求是: "不允许列入黑名单的单词出现在特定的 XML 标记中".

我正在尝试使用 XML 正则表达式模式的 xs:restriction。

我引用了以下链接:Restrict word list in XML schema

例如:列入黑名单的单词:byte,bing,ding

问题:如果单词以相同的字母 (b) 开头,则 byte 通过 bing 条件,反之亦然

我可以使用 AND 运算符吗?还有其他更简单的方法吗?

提前致谢!!

【问题讨论】:

    标签: xml regex blacklist


    【解决方案1】:

    如果可能的话,XSD 1.1 可能是最好的选择。其他答案已经涵盖了这一点,我倾向于相信他们:-)

    在 XSD 1.0 中,堆叠否定的唯一方法是使用否定集重复限制条件 (xs:pattern),每个(正)断言一个,例如:

    <xs:pattern value="([^(byte)]" />
    <xs:pattern value="([^(bing)])" />
    <xs:pattern value="([^(ding)])" />
    

    您还可以进一步指定每个单词、每个字母等的大小写。

    只要你否定你“列入黑名单”的整个事情,你就应该能够用相对易读的模式来构建它。

    【讨论】:

      【解决方案2】:

      根据 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很重要,否则会失败

      【讨论】:

      • Constants 在什么包中?
      【解决方案3】:

      在 XSD 1.1 中,您可以这样做:

      <xs:assert test="not(tokenize($value, '\s+') = ('byte', 'bing', 'ding'))"/>
      

      Saxon 和 Xerces 目前支持 XSD 1.1。

      【讨论】:

      • 非常感谢迈克尔!我尝试下载最新的 Xerces jar 并尝试解析 xml,但不知何故它没有检测到任何 XSD 1.1 语法。
      • 另外,如果我在 jre/rt.jar 和 xerces 中反编译 XMLScanner.class,方法 versionSupported() 会检查 jre/rt.jar 中的 1.0 和 1.1,但在 xerces.jar 中仅检查对于 1.0。
      • 有关 Xerces 对 XSD 1.1 的支持的信息可以在这里找到:xerces.apache.org/xerces2-j/faq-xs.html - 但是,我无法进一步帮助您,因为我自己没有尝试过。
      • 感谢您的帮助迈克尔。 1.1 支持在我错过的 beta 版 Xerces jar 中。我还必须将 $value 更改为 @name 才能使我的代码正常工作。我已经用我的答案更新了问题。
      【解决方案4】:

      在最初的问题中,它相对简单,将每个禁止的单词翻译成一个允许的模式列表。但在这种情况下,结果列表会发生冲突,因此您必须在生成完整的模式列表时同时考虑所有单词:

      • 以除bd 以外的任何内容开头
      • b 开头,下一个字符不是yi
      • by 开头,下一个字符不是t
      • byt 开头,下一个字符不是e
      • byte 开头并且至少还有一个字符
      • bytbyb
      • d 开头,下一个字符不是i
      • bidi 开头,下一个字符不是n
      • bindin 开头,下一个字符不是g
      • bingding 开头并且至少还有一个字符
      • binbibdindid

      结果:

      <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 所说,我希望同时出现更好的解决方案。

      【讨论】:

      • 嗨艾伦,感谢您的建议。实际上我已经编写了一个程序来生成你以前的正则表达式。但后来我突然意识到同一个起始字母有问题。如果我在 XSD1.1 中做不到,我会尝试编写一个程序。不过还是谢谢!
      • 没问题。找到解决方案后不要忘记更新此 Q/A。
      • 感谢您的帮助艾伦。我已经用我的实现更新了我的问题。
      • 重复这个模式怎么样? XSD 只是测试所有模式;如果内容与其中的 all 不匹配,则会失败。所以你只需要 (NOT X) AND (NOT Y) AND...
      【解决方案5】:

      无论你做什么,你都错了;而且我们无法通过阅读您引用的那个长线程来真正弄清楚您做了什么,所以您必须告诉我们。告诉我们您想要实现的目标可能也是一个好主意,因为可能有更好的方法。撇开别的不说,自 2009 年以来世界一直在发展,您或许可以使用 XSD 1.1。

      【讨论】:

      • 嗨迈克尔,感谢您的信息!我已经更新了这个问题。我希望它现在更清楚。有没有更好的方法来限制 XSD 1.1 中的单词?
      猜你喜欢
      • 1970-01-01
      • 2021-05-06
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 2011-11-04
      • 1970-01-01
      相关资源
      最近更新 更多