У меня есть несколько довольно больших сложных документов xml, которые мне нужно выполнить. Xmlns определен в верхней части документа, однако URL-адрес, на который указывает это, больше не доступен.
Какой лучший способ проанализировать файл для получения важных данных с помощью С#?
Я попытался загрузить его в набор данных, но иногда получал бы ошибки: Таблица (конечная точка) не может быть дочерней таблицей для себя в вложенных отношениях. или Невозможно добавить столбец SimpleContent в таблицу, содержащую столбцы элементов или вложенные отношения.
XPath был моим следующим портом захода, но у меня были проблемы из-за отсутствия пространства имен.
Я подозреваю, что это серьезно ограничивает мои варианты, но есть ли у кого-нибудь какие-либо предложения?
Фрагмент документа XML:
<?xml version="1.0" encoding="UTF-8"?>
<cdr:cdr_set xmlns:cdr="http://www.naturalconvergence.com/schema/cdr/v3/cdr">
<!-- Copyright (c) 2001-2009, all rights reserved -->
<cdr:cdr xmlns:cdr="http://www.naturalconvergence.com/schema/cdr/v3/cdr">
<cdr:call_id>2040-1247062136726-5485131</cdr:call_id>
<cdr:cdr_id>1</cdr:cdr_id>
<cdr:status>Normal</cdr:status>
<cdr:responsibility>
<cdr:tenant id="17">
<cdr:name>SpiriTel plc</cdr:name>
</cdr:tenant>
<cdr:site id="45">
<cdr:name>KWS</cdr:name>
<cdr:time_zone>GB</cdr:time_zone>
</cdr:site>
</cdr:responsibility>
<cdr:originator type="sipGateway">
<cdr:sipGateway id="3">
<cdr:name>Audiocodes-91</cdr:name>
</cdr:sipGateway>
</cdr:originator>
<cdr:terminator type="group">
<cdr:group>
<cdr:tenant id="17">
<cdr:name>SpiriTel plc</cdr:name>
</cdr:tenant>
<cdr:type>Broadcast</cdr:type>
<cdr:extension>6024</cdr:extension>
<cdr:name>OLD PMS DDIS DO NOT USE</cdr:name>
</cdr:group>
</cdr:terminator>
<cdr:initiation>Dialed</cdr:initiation>
<cdr:calling_number>02087893850</cdr:calling_number>
<cdr:dialed_number>01942760142</cdr:dialed_number>
<cdr:target>6024</cdr:target>
<cdr:direction>Inbound</cdr:direction>
<cdr:disposition>No Answer</cdr:disposition>
<cdr:timezone>GB</cdr:timezone>
<cdr:origination_timestamp>2009-07-08T15:08:56.727+01:00</cdr:origination_timestamp>
<cdr:release_timestamp>2009-07-08T15:09:26.493+01:00</cdr:release_timestamp>
<cdr:release_cause>Normal Clearing</cdr:release_cause>
<cdr:call_duration>PT29S</cdr:call_duration>
<cdr:redirected>false</cdr:redirected>
<cdr:conference>false</cdr:conference>
<cdr:transferred>false</cdr:transferred>
<cdr:estimated>false</cdr:estimated>
<cdr:interim>false</cdr:interim>
<cdr:segments>
<cdr:segment>
<cdr:originationTimestamp>2009-07-08T15:08:56.727+01:00</cdr:originationTimestamp>
<cdr:initiation>Dialed</cdr:initiation>
<cdr:call_id>2040-1247062136726-5485131</cdr:call_id>
<cdr:originator type="sipGateway">
<cdr:sipGateway id="3">
<cdr:name>Audiocodes-91</cdr:name>
</cdr:sipGateway>
</cdr:originator>
<cdr:termination_attempt>
<cdr:termination_timestamp>2009-07-08T15:08:56.728+01:00</cdr:termination_timestamp>
<cdr:terminator type="group">
<cdr:group>
<cdr:tenant id="17">
<cdr:name>SpiriTel plc</cdr:name>
</cdr:tenant>
<cdr:type>Broadcast</cdr:type>
<cdr:extension>6024</cdr:extension>
<cdr:name>OLD PMS DDIS DO NOT USE</cdr:name>
</cdr:group>
</cdr:terminator>
<cdr:provided_address>01942760142</cdr:provided_address>
<cdr:direction>Inbound</cdr:direction>
<cdr:disposition>No Answer</cdr:disposition>
</cdr:termination_attempt>
</cdr:segment>
</cdr:segments>
</cdr:cdr>
...
</cdr:cdr_set>
Каждая запись, по сути, одна и та же, но иногда существуют различия, например, некоторые из полей могут отсутствовать, если они не требуются.
Эти значения в файле xml являются идентификаторами, а не локаторами. Если вы не собираетесь загружать схему, она не нужна вообще и может быть "флибу", если это необходимо. Я ожидаю, что лучше всего просто загрузить его в XmlDocument
/XDocument
и попытаться получить доступ к данным.
Например:
XmlDocument doc = new XmlDocument();
doc.Load("cdr.xml");
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("cdr", "http://www.naturalconvergence.com/schema/cdr/v3/cdr");
XmlElement el = (XmlElement)doc.SelectSingleNode(
"cdr:cdr_set/cdr:cdr/cdr:originator", ns);
Console.WriteLine(el.GetAttribute("type"));
или перебрать элементы cdr
:
foreach (XmlElement cdr in doc.SelectNodes("/cdr:cdr_set/cdr:cdr", ns))
{
Console.WriteLine(cdr.SelectSingleNode("cdr:call_id", ns).InnerText);
}
Обратите внимание, что псевдонимы, используемые в документе, в значительной степени не связаны с псевдонимами, используемыми в XmlNamespaceManager
, поэтому вам нужно повторно объявить об этом. Я мог бы использовать x
как мой псевдоним на С# так же легко.
Конечно, если вы предпочитаете работать с объектной моделью; запустите его через xsd
(где cdr.xml
- ваш пример файла):
xsd cdr.xml
xsd cdr.xsd /classes
Теперь вы можете загрузить его с помощью XmlSerializer
.
alternativley загружает его в Xdocument и использует linq2XML?... хотя вы можете просто получить ту же ошибку.
Я не знаю, какие данные вам нужны, поэтому сложно предложить запрос. В большинстве случаев я лично предпочитаю использовать XDocument для xmlDocument.
Единственная проблема с автоматической генерацией XSD заключается в том, что она может привести к тому, что ваши типы данных будут очень плохо ошибочными, если вы не используете кусочек данных хорошего размера.
XmlSerializer
фактически отказался загружать ...