2009-07-10 88 views
2

我有一些數量相當大,複雜的xml文檔,我需要循環。文檔頂部定義了xmlns,但指向的URL不再可用。當名稱空間不再可用時解析xml文檔

什麼是解析文件以從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> 

每個條目基本上是相同的,但有時會有差異,如某些字段可能會丟失,如果不需要他們。

+0

(示例更新重新評論) – 2009-07-10 10:17:18

回答

5

這些xml文件中的值是標識符而不是定位器。除非你期望下載一個模式,否則根本不需要它,如果需要的話可以是「flibble」。我希望最好的辦法是將其加載到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使用的別名,因此你需要重新申報。我本可以很容易地在C#中使用x作爲我的別名。


當然,如果您更喜歡使用對象模型;通過xsd運行(其中cdr.xml就是你們的榜樣文件):

xsd cdr.xml 
xsd cdr.xsd /classes 

現在你可以用XmlSerializer加載它。

+0

我試過這個和行 XmlNodeList nodes = root。的SelectNodes( 「/ CDR:CDR」); 會生成「名稱空間管理器或XsltContext需要的異常,該查詢具有前綴,變量或用戶定義的函數。」 – 2009-07-10 09:59:13

+0

(對問題的回答) – 2009-07-10 10:02:02

1

alternativley加載到Xdocument並使用linq2XML? ...雖然你可能會得到相同的錯誤。

我不知道你想要什麼數據,所以很難建議查詢。 我個人更喜歡現在在大多數情況下使用XDocument到xmlDocument。

自動生成XSD的唯一問題是,如果您沒有使用大小合適的示例數據,它可能會讓您的數據類型非常錯誤。

相關問題