Подтвердить что ты не робот

Как определить, является ли строка xml?

У нас есть строковое поле, которое может содержать XML или обычный текст. XML не содержит заголовка <?xml, и ни один корневой элемент, т.е. Не сформирован правильно.

Нам нужно иметь возможность редактировать XML-данные, освобождать элементы и значения атрибутов, оставляя только их имена, поэтому мне нужно проверить, является ли эта строка XML перед ее исправлением.

В настоящее время я использую этот подход:

string redact(string eventDetail)
{
    string detail = eventDetail.Trim();
    if (!detail.StartsWith("<") && !detail.EndsWith(">")) return eventDetail;
    ...

Есть ли лучший способ?

Есть ли какие-либо краевые случаи, которые этот подход мог бы пропустить?

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

Здесь пример XML-данных, кроме отсутствующего корневого элемента (который не используется для экономии места, поскольку будет много данных), мы можем предположить, что он хорошо сформирован:

<TableName FirstField="Foo" SecondField="Bar" /> 
<TableName FirstField="Foo" SecondField="Bar" /> 
...

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

РЕШЕНИЕ

Основываясь на нескольких комментариях (спасибо, ребята!)

string redact(string eventDetail)
{
    if (string.IsNullOrEmpty(eventDetail)) return eventDetail; //+1 for unit tests :)
    string detail = eventDetail.Trim();
    if (!detail.StartsWith("<") && !detail.EndsWith(">")) return eventDetail;
    XmlDocument xml = new XmlDocument();
    try
    {
        xml.LoadXml(string.Format("<Root>{0}</Root>", detail));
    }
    catch (XmlException e)
    {
        log.WarnFormat("Data NOT redacted. Caught {0} loading eventDetail {1}", e.Message, eventDetail);
        return eventDetail;
    }
    ... // redact
4b9b3361

Ответ 1

Одной из возможностей является объединение обоих решений. Вы можете использовать свой метод redact и попытаться загрузить его (внутри if). Таким образом, вы только попытаетесь загрузить то, что может быть хорошо сформированным xml, и отбросить большинство записей, отличных от xml.

Ответ 2

Если вы собираетесь принять не правильно сформированный XML в первую очередь, я думаю, что поймать исключение - лучший способ справиться с этим.

Ответ 3

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

Ответ 4

Зависит от того, насколько точным является ваш тест. Учитывая, что у вас уже нет официального < xml, вы уже пытаетесь обнаружить что-то, что не является XML. В идеале вы должны анализировать текст с помощью полного XML-парсера (как вы предлагаете LoadXML); все, что он отвергает, - это не XML. Вопрос в том, что вас беспокоит, если вы принимаете строку, отличную от XML? Например, вы согласны с принятием

  <the quick brown fox jumped over the lazy dog back>

как XML и лишить его? Если это так, ваша техника в порядке. Если нет, вы должны решить, насколько жесткий тест вы хотите и код распознавателя с такой степенью герметичности.

Ответ 5

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

Неудачное решение такого рода, я думаю, что у вас все хорошо (для проверки того, что он начинается и заканчивается этими символами).

Нам нужно больше узнать о формате данных.

Ответ 6

Если XML не содержит корневого элемента (т.е. это фрагмент XML, а не полный документ), то также будет вполне корректным образец, но не будет соответствовать вашему детектору:

foo<bar/>baz

Фактически любая текстовая строка будет действительным фрагментом XML (рассмотрим, был ли исходный документ XML только корневым элементом, который обертывал какой-то текст, и вы удаляете теги корневого элемента)!

Ответ 7

try
{
    XmlDocument myDoc = new XmlDocument();
    myDoc.LoadXml(myString);
}
catch(XmlException ex)
{
    //take care of the exception
}