2013-07-26 6 views
5

Edytuję serię plików XML i muszę usunąć wszystkie atrybuty o nazwie "foo". Ten atrybut pojawia się w więcej niż jednym typie elementu. Przykładowy fragment z XML mogą być:Usuń wszystkie atrybuty XML o podanej nazwie

<bodymatter id="######"> 
    <level1 id="######"> 
    <pagenum page="#####" id="######" foo="######" /> 
    <h1 id="#####" foo="#####">Header</h1> 
    <imggroup id="#######"> 
       . 
       . 
       etc. 

Najlepszym rozwiązaniem mam używa wyrażenia regularnego:

Regex regex = new Regex("foo=\"" + ".*?" + "\"", RegexOptions.Singleline); 
content = regex.Replace(content, ""); 

wiem wbudowany w parsera XML może pomóc, ale idealnie chcę zrobić proste zamienniki XML/usunięcie bez konieczności zajmowania się bagażem całego parsera XML. Czy Regex jest najlepszym rozwiązaniem w tym przypadku?

Edit:

Po niektórych badań w klasie XmlDocument, tutaj jest jednym z możliwych rozwiązań wymyśliłem (aby usunąć więcej niż jeden typ atrybutu przechowywane w tablicy „id”):

private void removeAttributesbyName(string[] ids) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(path); 
    XmlNodeList xnlNodes = doc.GetElementsByTagName("*"); 
    foreach (XmlElement el in xnlNodes) 
    { 
     for (int i = 0; i <= ids.Length - 1; i++) 
     { 
      if (el.HasAttribute(ids[i])) 
      { 
       el.RemoveAttribute(ids[i]); 
      } 
      if (el.HasChildNodes) 
      { 
       foreach (XmlNode child in el.ChildNodes) 
       { 
        if (child is XmlElement && (child as XmlElement).HasAttribute(ids[i])) 
        { 
         (child as XmlElement).RemoveAttribute(ids[i]); 
        } 
       } 
      } 
     } 
    } 
} 

Nie wiem, czy to jest tak wydajne, jak to tylko możliwe, ale testowałem i wydaje się, że działa dobrze.

+3

Regex i XML nie mieszają się. –

+0

RegeXml, niezbyt ładna rzecz – Jonesopolis

+0

Zmieniłem twój tytuł. Zobacz, "[Czy w tytułach pytania powinny znaleźć się" znaczniki "?] (Http://meta.stackexchange.com/questions/19190/)", gdzie konsensus brzmi "nie, nie powinien". –

Odpowiedz

7

Nie używaj wyrażenia regularnego do manipulacji XML. Możesz użyć Linq do XML:

XDocument xdoc = XDocument.Parse(xml); 
foreach (var node in xdoc.Descendants().Where(e => e.Attribute("foo")!=null)) 
{ 
    node.Attribute("foo").Remove(); 
} 

string result = xdoc.ToString(); 
+0

Pomyślałem, że Regex nie był dobrym pomysłem, ale nie chciałem przeglądać wszystkich bibliotek metod dla wbudowanych analizatorów XML. Teraz jednak zajmuję się klasą XmlDocument i mogę również wykorzystać to, co tu masz. Dzięki! –

2

Czy Regex jest najlepszym rozwiązaniem w tym przypadku?

nr

Będziemy chcieli wykorzystać coś, co działa na XML na poziomie obiektu (jako XmlElement, na przykład), a nie na poziomie string.

0

Używam następujących elementów do usuwania przestrzeni nazw. Może to również działać w usuwaniu atrybutów z innych węzłów.

 FileStream fs = new FileStream(filePath, FileMode.Open); 

     StreamReader sr = new StreamReader(fs); 

     DataSet ds = new DataSet(); 
     ds.ReadXml(sr); 
     ds.Namespace = ""; 

     string outXML = ds.GetXml(); 
     ds.Dispose(); 
     sr.Dispose(); 
     fs.Dispose();