2010-12-10 29 views
1

我有一个巨大的XML文档。自动完成过滤器的Xpath和正则表达式

类似的东西

<?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 = @名称和前缀也许是:“西班牙”或“西班牙”或“西班牙”,它给我0解决方案

+0

如果你的过滤器是用户提供的东西,那么一定要以某种方式逃避它。例如,如果用户输入一些包含xpath特殊字符的字符串,那么'SelectNodes'可能会抛出 – 2010-12-10 14:47:53

+0

好问题,+1。请参阅我的答案,以获取更为一般的解决方案,该解决方案允许任何非字母字符分隔任何单词。 :) – 2010-12-10 21:09:06

+0

@ Christophe-Debove:谢谢你让这个问题更加有趣。看到我更新的答案。 :) – 2010-12-15 14:54:48

回答

1

UPDATE: 由于原来的问题是改变将要求识别单词“西班牙”不仅在所有可能的市值也包括重音符号,我已经更新了下面的解决方案,因此现在“西班牙“和/或被正确识别。

这里比@Alejandro更通用的解决方案:

如果我们要选择所有元素,其name属性包含单词“西班牙”,在任何资本,如果可能的话分隔符都非字母字符,然后

这个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' 

and

'âÂABCDEFGHïÏIJKLMNOPQRSTUVWXYZ' 

$vAlpha必须用$vLower$vUpper的连接代替。

+0

+1是的,这也是一个很好的解决方案,添加删除标点符号的要求 – 2010-12-10 21:23:13

+0

@dimitre你可以看一下我对口音的编辑 – 2010-12-15 11:00:41

+0

@ Christophe-Debove:谢谢你让这个问题更加有趣。看到我更新的答案。 :) – 2010-12-15 14:54:11

3

使用

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

编辑:现在的问题发生了变化,但得到的答复仍然是...

在翻译模式只需添加这些变化,如:

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

注:当然,一个更一般的表达式将需要一个更一般的翻译模式。

+1

哟Alejandro你能解释一下加concat的用法吗? – Treemonkey 2010-12-10 14:44:17

+1

@Treemonkey:是的。 '包含(@ name,'spain')'会匹配“spainly”。 – 2010-12-10 14:52:57

+0

如果名称只是name =“spain”,那么它是否仍然会获得元素,因为没有空格?感谢回复:) – Treemonkey 2010-12-10 14:59:45

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')]");