Тестирование того, является ли что-то синтаксическое XML в С#
Кто-нибудь знает быстрый способ проверить, что строка обрабатывается как XML в С#? Предпочтительно, что-то быстрый, низкий ресурс, который возвращает логическое значение независимо от того, будет ли он разбираться.
Я работаю над приложением базы данных, которое касается ошибок, которые иногда хранятся как XML, а иногда и нет. Следовательно, я бы хотел просто проверить строку, которую я быстро извлекаю из базы данных (содержащуюся в DataTable)... и не должен прибегать к какому-либо запросу try/catch {} или другим kludges... если только это единственный способ сделать это.
Ответы
Ответ 1
Похоже, что вы иногда возвращаете XML, а иногда вы получаете "простой" (не XML) текст.
В этом случае вы можете просто проверить, что текст начинается с <
:
if (!string.IsNullOrEmpty(str) && str.TrimStart().StartsWith("<"))
var doc = XDocument.Parse(str);
Поскольку "простые" сообщения, кажется, не начинаются с <
это может быть разумным. Единственное, что вам нужно решить, это что делать в крайнем случае, если у вас есть не-XML текст, который начинается с <
?
Если бы это был я, я бы по умолчанию попытался разобрать его и поймать исключение:
if (!string.IsNullOrEmpty(str) && str.TrimStart().StartsWith("<"))
{
try
{
var doc = XDocument.Parse(str);
return //???
}
catch(Exception ex)
return str;
}
else
{
return str;
}
Таким образом, единственное время, когда у вас возникают накладные расходы на выброшенное исключение, это когда у вас есть сообщение, которое начинается с <
но не является допустимым XML.
Ответ 2
Вы можете попытаться проанализировать строку в XDocument. Если это не удается проанализировать, вы знаете, что это неверно.
string xml = "";
XDocument document = XDocument.Parse(xml);
И если вы не хотите, чтобы уродливый try/catch был видимым, вы можете бросить его в метод расширения в классе строк...
public static bool IsValidXml(this string xml)
{
try
{
XDocument.Parse(xml);
return true;
}
catch
{
return false;
}
}
Тогда ваш код просто выглядит как if (mystring.IsValidXml()) {
Ответ 3
Единственный способ узнать, действительно ли что-то на самом деле разобрать, - это... попытаться разобрать его.
Документ XMl должен (но не обязательно) иметь объявление XML во главе файла, следуя спецификации (если присутствует). Он должен выглядеть примерно так:
<?xml version="1.0" encoding="UTF-8" ?>
Хотя атрибут кодирования, я полагаю, является необязательным (по умолчанию используется UTF-8. Он также может иметь атрибут standalone
, значение которого yes
или no
. Если это присутствует, это довольно хороший индикатор что документ должен быть действительным XML.
Riffing on @GaryWalker отличный ответ, что-то вроде этого примерно так же хорошо, как и получается, я думаю (хотя для настройки может потребоваться некоторая настройка, op resolver возможно). Просто для ударов я сгенерировал случайный XML файл размером 300 МБ, используя XMark xmlgen
(http://www.xml-benchmark.org/): проверка его с помощью приведенного ниже кода занимает 1,7 – 1,8 секунды истекшего времени на моем настольном компьютере.
public static bool IsMinimallyValidXml( Stream stream )
{
XmlReaderSettings settings = new XmlReaderSettings
{
CheckCharacters = true ,
ConformanceLevel = ConformanceLevel.Document ,
DtdProcessing = DtdProcessing.Ignore ,
IgnoreComments = true ,
IgnoreProcessingInstructions = true ,
IgnoreWhitespace = true ,
ValidationFlags = XmlSchemaValidationFlags.None ,
ValidationType = ValidationType.None ,
} ;
bool isValid ;
using ( XmlReader xmlReader = XmlReader.Create( stream , settings ) )
{
try
{
while ( xmlReader.Read() )
{
; // This space intentionally left blank
}
isValid = true ;
}
catch (XmlException)
{
isValid = false ;
}
}
return isValid ;
}
static void Main( string[] args )
{
string text = "<foo>This &SomeEntity; is about as simple as it gets.</foo>" ;
Stream stream = new MemoryStream( Encoding.UTF8.GetBytes(text) ) ;
bool isValid = IsMinimallyValidXml( stream ) ;
return ;
}
Ответ 4
Существует несколько способов определить, является ли XML действительным. Я в основном делаю два шага.
Проверьте, начинается ли он с требуемого тега XML (что-то типа)
bool result = xmlToParse.BeginsWith("<?xml");
затем убедитесь, что есть равные <
и >
(что-то типа)
result = xmlToParse.Count(c => c == '<') == xmlToParse.Count(c => c == '>');
помимо базовой проверки, он становится чем-то, что процесс, который на самом деле знаком с XML, должен выполняться (NOT regex), чтобы гарантировать его синтаксический анализ.
Ответ 5
Лучший ответ, который я вам представлял для тестового XML, который я знаю, Каков самый быстрый способ программной проверки корректности XML файлов на С#?
formness-of-xml-file "Он использует XMLReader для эффективного выполнения.