从XML标记中提取选定节点值的方式

问题描述:

考虑到(标本 - 实际标记可能更复杂)标记和下面列出的约束,是否有人可以提出一种解决方案(C#)比步行更有效整棵树检索{“@@ value1 @@”,“@@ value2 @@”,“@@ value3 @@”},即在实际使用标记时将被替换的标记列表。从XML标记中提取选定节点值的方式

注意:我无法控制正在替换的标记的标记,结构或格式/命名。

<markup> 
    <element1 attributea="blah">@@[email protected]@</element1> 
    <element2>@@[email protected]@</element2> 
    <element3> 
     <element3point1>@@[email protected]@</element3point1> 
     <element3point2>@@[email protected]@</element3point2> 
     <element3point3>apple</element3point3> 
    <element3> 
    <element4>pear</element4> 
</markup> 
+0

是否启动序列化为文字,或者已经被解析?简单的正则表达式搜索,如果它已经序列化。 – p00ya 2009-07-16 09:35:03

+0

你只是想获取令牌,或者需要替换它们? – amazedsaint 2009-07-16 09:42:39

+0

@amazedsaint - 只要他们=) – Rob 2009-07-16 09:55:12

如何:

var keys = new HashSet<string>(); 
    Regex.Replace(input, "@@[^@][email protected]@", match => { 
     keys.Add(match.Value); 
     return ""; // doesn't matter 
    }); 
    foreach (string key in keys) { 
     Console.WriteLine(key); 
    } 

此:

  • 不打扰解析XML(只是字符串操作)
  • 只包括唯一值(无需返回MatchCollection与我们不想要的副本)

但是,它可以建立一个较大的字符串,那么也许只是Matches

var matches = Regex.Matches(input, "@@[^@][email protected]@"); 
var result = matches.Cast<Match>().Select(m => m.Value).Distinct(); 
foreach (string s in result) { 
    Console.WriteLine(s); 
} 
+0

工作了一个款待(第二个片段),谢谢! =) – Rob 2009-07-16 09:54:41

我写了一个快速编与您的示例,这应该做的伎俩。

class Program 
    { 
     //I just copied your stuff to Test.xml 
     static void Main(string[] args) 
     { 
      XDocument doc = XDocument.Load("Test.xml"); 
      var verbs=new Dictionary<string,string>(); 
      //Add the values to replace ehre 
      verbs.Add("@@[email protected]@", "mango"); 
      verbs.Add("@@[email protected]@", "potato"); 
      ReplaceStuff(verbs, doc.Root.Elements()); 
      doc.Save("Test2.xml"); 
     } 

     //A simple replace class 
     static void ReplaceStuff(Dictionary<string,string> verbs,IEnumerable<XElement> elements) 
     { 
      foreach (var e in elements) 
      { 
       if (e.Elements().Count() > 0) 
        ReplaceStuff(verbs, e.Elements()); 
       else 
       { 
        if (verbs.ContainsKey(e.Value.Trim())) 
         e.Value = verbs[e.Value]; 
       } 
      } 
     } 
    }