Как я могу отсоединить смешанный контент XML с помощью инструментов C # XML, а не регулярное выражение? - PullRequest
0 голосов
/ 08 июня 2018

Я использую «приложение 1» для создания и редактирования файлов xhtml.Он имеет возможность вводить аннотации в содержимое непустых элементов, таких как p, h1, h2, td и т. Д., Что приводит к смешанным фрагментам XML-кода, например:

<p>Hello <NS1:annotation [...SomeAttributes...]>everybody</NS1:annotation> out there!</p>

Для целей перевода Iнеобходимо экспортировать эти файлы xhtml в «приложение 2», которое не может работать с этими внутренними элементами.Поскольку аннотации не являются частью желаемого содержимого в переводах, удаление их перед экспортом в приложение 2 было бы идеальным обходным путем:

<p>Hello everybody out there!</p>

Удаление узлов из XmlDocument надежно находит иудаляет внутренние элементы xml, но также удаляет содержимое элемента аннотации - теряя слово «все» в приведенном выше примере:

<p>Hello out there!</p>

Что мне нужно, так это «развязать» содержимое этих внутренних элементовв содержание родительского элемента.Но до сих пор я не нашел метод, использующий инструменты c # xml, выполняющие эту работу.

До сих пор я сначала сохранял файл xhtml, заново открывал его как текстовый файл и использовал regedits для удаления аннотации.Я даже могу использовать для этого методы c #:

TextFile txt = new TextFile();
string s = txt.ReadFile(filename);

string pattern = @"<NS1:annotation.+>(.+)</NS1:annotation>";
string input = s;
string replacement = "$1";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);

TextFile.Write((filename,result););

Это, несомненно, лучшее решение, поскольку оно не теряет содержание аннотации, но мне интересно, действительно ли не существует решения, основанного на c # Xml-инструменты, которые делают эту работу.

Кто-нибудь знает это?

1 Ответ

0 голосов
/ 08 июня 2018

Я думаю, что нашел ответ, используя XmlDocument.Ключевым моментом является то, что в смешанных узлах xml текст, окружающий узел, также может быть представлен как узлы xml.Я не знал об этом ...

Следующая функция освобождает содержимое смешанного узла и высвобождает его в содержимое родительского узла.Я не тестировал его для узлов, содержащих несколько аннотаций, но на данный момент мне этого достаточно ...

private void removeAnnotations(XmlDocument doc)
{
    XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
    manager.AddNamespace("NS1","http://www.someurl.net");
    XmlNodeList annotations = doc.SelectNodes("//NS1:annotation", manager);

    int i = 0;
    while (i < annotations.Count) 
    {
      //in mixed xml the Siblings are xml text nodes. Therefore we write them into buffers:        
      string s0 = "";
      if(annotations[i].PreviousSibling != null) s0 = annotations[i].PreviousSibling.InnerText;        
      string s2 = "";
      if(annotations[i].NextSibling != null) s2 = annotations[i].NextSibling.InnerText;
      //buffer the content of the annotation itself
      string s1 = annotations[i].InnerText;       
      //buffer the link to the parent node before we remove the annotation,
      XmlNode parent = annotations[i].ParentNode;
      //now remove the annotation
      parent.RemoveChild(annotations[i]);
      //and apply the new Text to the parent element
      parent.InnerText = s0 + s1 + s2;
      i++;
    }
}
...