Разбор XML-документа, когда пространство имен больше не доступно - PullRequest
2 голосов
/ 10 июля 2009

У меня есть несколько довольно больших, сложных XML-документов, которые мне нужно просмотреть. Xmlns определяется в верхней части документа, однако URL, на который он указывает, больше не доступен.

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

Я пытался загрузить его в набор данных, но иногда получал ошибки: Таблица (конечная точка) не может быть дочерней таблицей для себя во вложенных отношениях. или же Невозможно добавить столбец 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>

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

Ответы [ 2 ]

5 голосов
/ 10 июля 2009

Этими значениями в 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 в качестве своего псевдонима в C # так же легко.


Конечно, если вы предпочитаете работать с объектной моделью; запустите его через xsd (где cdr.xml - ваш файл примера):

xsd cdr.xml
xsd cdr.xsd /classes

Теперь вы можете загрузить его с помощью XmlSerializer.

1 голос
/ 10 июля 2009

альтернативей загрузить его в Xdocument и использовать linq2XML? ... хотя вы можете просто получить ту же ошибку.

Я не знаю, какие данные вам нужны, поэтому сложно предложить запрос. Лично я в большинстве случаев предпочитаю использовать XDocument вместо xmlDocument.

единственная проблема с автоматическим генерированием XSD заключается в том, что он может очень неправильно использовать ваши типы данных, если вы не используете кусок выборочных данных большого размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...