Удалить весь текст, не заключенный в скобки XML

Я хочу удалить весь недопустимый текст из документа XML. Я считаю любой текст, не заключенный в скобки <> XML, недействительным и хочу удалить его перед переводом.

Из этого поста Регулярное выражение для удаления текста вне тегов в строке - объясняется, как сопоставлять скобки XML вместе. Однако в моем примере он не очищает текст вне XML, как видно в этом примере. https://regex101.com/r/6iUyia/1

Я не думаю, что этот конкретный пример был задан на S/O ранее из моего первоначального исследования.

В настоящее время в моем коде у меня есть этот XML в виде строки, прежде чем я потом создам из него XDocument. Таким образом, у меня потенциально есть строковые методы, методы Regex и XDocument, чтобы помочь в их удалении, кроме того, в этих документах может содержаться более одного недопустимого XML-кода. Кроме того, я не хочу использовать XSLT для удаления этих значений.

Одна из самых элементарных идей, которые я пытался и не смог составить, состоял в том, чтобы перебрать строку как массив символов и попытаться удалить ее, если она находится за пределами ">" и "<", но решил, что должен быть лучший способ добиться этого (отсюда и вопрос)

Это пример ввода с недопустимым текстом, отображаемым между nested-A и nested-B

 <ASchema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns:fn="http://www.w3.org/2005/xpath-functions">
   <A>
         <nested-A>valid text</nested-A>
         Remove text not inside valid xml braces
         <nested-B>more valid text here</nested-B>
   </A>
</ASchema>

Я ожидаю, что вывод будет в формате, как показано ниже.

 <ASchema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns:fn="http://www.w3.org/2005/xpath-functions">
   <A>
         <nested-A>valid text</nested-A>
         <nested-B>more valid text here</nested-B>
   </A>
</ASchema>

1 ответ

Решение

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

XmlDocument doc = new XmlDocument();
doc.LoadXml(str);
var json = JsonConvert.SerializeXmlNode(doc);

string result = JToken.Parse(json).RemoveFields().ToString(Newtonsoft.Json.Formatting.None);
var xml = (XmlDocument)JsonConvert.DeserializeXmlNode(result);

Где RemoveFields определены как

public static class Extensions
{
public static JToken RemoveFields(this JToken token)
{
    JContainer container = token as JContainer;
    if (container == null) return token;

    List<JToken> removeList = new List<JToken>();
    foreach (JToken el in container.Children())
    {
        JProperty p = el as JProperty;
        if (p != null && p.Name.StartsWith("#"))
        {
            removeList.Add(el);
        }
        el.RemoveFields();
    }

    foreach (JToken el in removeList)
        el.Remove();

    return token;
}
}

Выход

<ASchema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns:fn="http://www.w3.org/2005/xpath-functions">
   <A>
      <nested-A>valid text</nested-A>
      <nested-B>more valid text here</nested-B>
   </A>
</ASchema>

Обратите внимание, что я использую Json.net в приведенном выше коде

Другие вопросы по тегам