当名称空间不再可用时解析xml文档
我有一些数量相当大,复杂的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>
每个条目基本上是相同的,但有时会有差异,如某些字段可能会丢失,如果不需要他们。
这些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
加载它。
我试过这个和行 XmlNodeList nodes = root。的SelectNodes( “/ CDR:CDR”); 会生成“名称空间管理器或XsltContext需要的异常,该查询具有前缀,变量或用户定义的函数。” – 2009-07-10 09:59:13
(对问题的回答) – 2009-07-10 10:02:02
alternativley加载到Xdocument并使用linq2XML? ...虽然你可能会得到相同的错误。
我不知道你想要什么数据,所以很难建议查询。 我个人更喜欢现在在大多数情况下使用XDocument到xmlDocument。
自动生成XSD的唯一问题是,如果您没有使用大小合适的示例数据,它可能会让您的数据类型非常错误。
(示例更新重新评论) – 2009-07-10 10:17:18