【问题标题】:Xpath and regex for autocompletion filter用于自动完成过滤器的 Xpath 和正则表达式
【发布时间】:2010-12-10 14:35:26
【问题描述】:

我有一个巨大的 xml 文档。

类似的东西

<?xml version="1.0" encoding="utf-8"?>
<elements>
 <element id="1" name="france" />
 <element id="2" name="usa" />
 <element id="3" name="Spaïn" />
 <element id="4" name="spain and africa" />
 <element id="5" name="italie and Spâin" />
</elements>

我想要这样的东西:

string str = "spain";
XmlDocument xmlDoc = new XmlDocument();                
xmlDoc.LoadXml(myXML);
// Xpath with regex or something very veloce
XmlNodeList xmlNodeList =  xmlDoc.SelectNodes("//element"+ something);  

xmlNodeList 将包含:

<element id="3" name="Spaïn" />
<element id="4" name="france with spâin and africa" />
<element id="5" name="italie and Spain" />

它必须忽略大小写
和重音

目前为止

XmlNodeList xmlNodeList = xmlDoc.SelectNodes("/*/*[contains(concat(' ',translate(translate(@n,translate(@n, 'aaabcdefghiiijklmnopqrstuvwxyzâÂABCDEFGHïÏIJKLMNOPQRSTUVWXYZ', ''),''), 'âÂABCDEFGHïÏIJKLMNOPQRSTUVWXYZ','aaabcdefghiiijklmnopqrstuvwxyz'),' '),' "+prefix+" ')]");

@n = @name 和前缀可能是:“spain”或“Spain”或“Spaïn”,它给了我 0 个解决方案

【问题讨论】:

  • 如果您的过滤器是用户提供的,那么一定要以某种方式对其进行转义。例如,如果用户输入了一些包含 xpath 特殊字符的字符串,那么 SelectNodes 可能会抛出
  • 好问题,+1。请参阅我的答案以获得更通用的解决方案,该解决方案允许任何非字母字符分隔任何单词。 :)
  • @Christophe-Debove:感谢您让这个问题变得更加有趣。请参阅我的更新答案。 :)
  • @Christophe-Debove:我进行了详尽的搜索,看来我的解决方案可能是解决您的问题的唯一方法。特别是,没有一种方法可以在 RegEx 中为“A 的所有重音字符”或任何单个特定字符指定字符类。这意味着即使使用正则表达式,也必须枚举所有重音字符。因此,如果他决定改为编写正则表达式,将不会比我的解决方案更好。

标签: c# xml xpath xmldocument


【解决方案1】:

使用

//element[contains(concat(' ',translate(@name,'SPAIN','spain'),' '),' spain ')]

编辑:现在,问题变了,但答案依然存在……

只需在翻译模式中添加这些更改,例如:

//element[contains(concat(' ',
                          translate(@name,
                                    'SPAÂâIÏïN',
                                    'spaaaiiin'),
                          ' '),
                   ' spain ')]

注意:当然,更通用的表达式需要更通用的翻译模式。

【讨论】:

  • yo Alejandro 能解释一下添加 concat 的用法吗?
  • @Treemonkey:是的。 contains(@name,'spain') 将匹配“西班牙”。
  • 如果名称只是 name="spain" 因为没有空格,它还会获取元素吗?谢谢回复:)
  • @Treemonkey:是的,因为前导和尾随空格连接到@name
  • 您能否删除答案的 // 以使其具有语法颜色
【解决方案2】:
string str = "spain";
XmlDocument xmlDoc = new XmlDocument();                
xmlDoc.LoadXml(myXML);
// Xpath with regex or something very veloce
XmlNodeList xmlNodeList =  xmlDoc.SelectNodes("//element[contains(@name,'spain')]");  

【讨论】:

    【解决方案3】:

    更新: 由于更改了原始问题,增加了识别单词“Spain”的要求,不仅包括所有可能的大写字母,还包括重音字符,我已经更新了下面的解决方案,现在“Spain”与 â 和/ 或 ïÏ 被正确识别。

    这是一个比@Alejandro 更通用的解决方案

    如果我们要选择所有元素,其name 属性包含任何大小写的单词“Spain”,并且如果可能的单词分隔符都是非字母字符,那么

    这个 XPath 表达式

    /*/*[contains(
                  concat(' ',
                         translate(translate(@name,
                                             translate(@name, $vAlpha, ''),
                                             '                                                           '),
                                   $vUpper,
                                   $vLower),
                         ' '
                         ),
                  ' spain '
                  )
         ]
    

    应用于此 XML 文档时

    <elements>
     <element id="1" name="france" />
     <element id="2" name="usa" />
     <element id="3" name="Spaïn" />
     <element id="4" name="france with spâin and africa" />
     <element id="5" name="-Spain!" />
     <element id="6" name="spain and africa" />
     <element id="7" name="italie and Spain." />
    </elements>
    

    选择以下元素

    <element id="3" name="Spaïn"/>
    <element id="4" name="france with spâin and africa"/>
    <element id="5" name="-Spain!"/>
    <element id="6" name="spain and africa"/>
    <element id="7" name="italie and Spain."/>
    

    在上述 XPath 表达式 $vLower 中,$vUpper 必须分别替换为:

    'aaabcdefghiiijklmnopqrstuvwxyz'
    

    'âÂABCDEFGHïÏIJKLMNOPQRSTUVWXYZ'
    

    $vAlpha 必须替换为 $vLower$vUpper 的串联。

    【讨论】:

    • +1 是的,这也是一个很好的解决方案,添加删除标点符号的要求
    • @Christophe-Debove:感谢您让这个问题变得更加有趣。请参阅我的更新答案。 :)
    • @Dimitre 它可以工作,但我正在寻找更自动的东西,用你的方式我们不能避免错过一些 õ è ù 或琐碎(非拉丁)字符
    • @Christophe-Debove:不仅“它可以工作”,而且还有效!至于将其用作“自动”解决方案——是的,只需按照我的解决方案中演示的方式将所有重音字符添加到$vLower$vUpper 变量中——只有几个元音,每个元音只有一个少数重音变体。您介意 XPath 2.0 解决方案吗(您可能需要访问非标准 XPath (2.0) 引擎,例如 Saxon 或 XQSharp)?
    • @Dimitre 也许是我,但我没有到达让它工作我编辑我的问题以添加我的 C# 代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    相关资源
    最近更新 更多