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

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

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

Для целей перевода я должен экспортировать эти файлы 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-tools, которое выполняет эту работу.

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

1 ответ

Я думаю, что нашел ответ, используя 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++;
    }
}
Другие вопросы по тегам