【问题标题】:Parse xml ( edmx ) attribute with namespace使用命名空间解析 xml ( edmx ) 属性
【发布时间】:2013-06-06 06:52:17
【问题描述】:

我正在尝试从 edmx xml 解析 m:MaxDataServiceVersion 的值,其开头如下:

<edmx:Edmx Version="1.0">
<edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0">
<Schema Namespace="NorthwindModel">
<EntityType Name="Category">

以下代码返回需要的元素

string nav = navigator.SelectSingleNode("//*[local-name() = 'DataServices']");

但是我所有获取属性值的尝试都没有成功。这是我尝试过的:

string nav = navigator.SelectSingleNode("//*[local-name() = 'DataServices']").GetAttribute("@{m}MaxDataServiceVersion", "");
nav = navigator.SelectSingleNode("//*[local-name() = 'DataServices']").GetAttribute("m:MaxDataServiceVersion", "");
nav = navigator.SelectSingleNode("//*[local-name() = 'DataServices']").GetAttribute("MaxDataServiceVersion", "");
nav = navigator.SelectSingleNode("//*[local-name() = 'DataServices']").GetAttribute("MaxDataServiceVersion", "m");
nav = navigator.SelectSingleNode("//*[local-name() = 'DataServices']").GetAttribute("MaxDataServiceVersion", "edmx:m");

运行以下代码

XPathNodeIterator nodes = navigator.Select("//*[local-name() = 'DataServices']");
while (nodes.MoveNext())
{
    XPathNavigator navigator2 = nodes.Current.Clone();
    navigator2.MoveToFirstAttribute();
    Console.WriteLine("{0} = {1}", navigator2.Name, navigator2.Value);

    while (navigator2.MoveToNextAttribute())
    {
        Console.WriteLine("{0} = {1}", navigator2.Name, navigator2.Value);
    }

    Console.WriteLine();
}

将输出两个属性

m:DataServiceVersion = 1.0
m:MaxDataServiceVersion = 3.0

但我认为应该可以在不遍历所有这些的情况下获得所需的...

那么有没有办法在不循环的情况下获得m:MaxDataServiceVersion 值?

【问题讨论】:

    标签: c# .net xpath xml-parsing edmx


    【解决方案1】:

    XML 以

    开头
    <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"><edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
    

    所以访问每个DataServices 元素的属性的一种方法是

    XmlNamespaceManager nsMgr = new XmlNamespaceManager(navigator.NameTable);
    nsMgr.Add("edmx", "http://schemas.microsoft.com/ado/2007/06/edmx");
    
    foreach (XPathNavigator dataServices in navigator.Select("edmx:DataServices", nsMgr))
    {
      string version = dataServices.GetAttribute("MaxDataServiceVersion", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
    }
    

    如果你想要第一个这样的属性的属性值那么做

    nsMgr.Add("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
    string version = navigator.SelectSingleNode("//edmx:DataServices/@m:MaxDataServiceVersion", nsMgr).Value;
    

    应该够了。

    【讨论】:

    • 感谢您的回答,现在我在 chrome 中看到了架构 url,firefox 只是隐藏了它。有可能,网址会随时间变化吗?有没有办法动态确定?
    • 就我所知,命名空间 URL 相当稳定(尽管我知道更多 W3C 拥有的 URL,例如 http://www.w3.org/1999/xhtmlhttp://www.w3.org/1999/XSL/Transform)。可以在运行时读出命名空间,但我认为你应该在一个新问题中提出这个问题。
    • 您的代码有效,谢谢。但是有什么方法可以跳过属性的命名空间,类似于元素的 //*[local-name() = 'DataServices']?我的意思是将最后一行修改为字符串 version = navigator.SelectSingleNode("//*[local-name() = 'DataServices']/@m:MaxDataServiceVersion", nsMgr).Value;我可以跳过 edmx NS 定义。
    • 好吧,//*[local-name() = 'DataServices']/@*[local-name() = 'MaxDataServiceVersion'] 应该是可能的,但在我看来,忽略基于命名空间的 XML 中的命名空间不是一个好方法。使用它需要您自担风险。
    猜你喜欢
    • 1970-01-01
    • 2017-03-23
    • 2021-05-03
    • 2014-01-10
    • 1970-01-01
    • 2010-11-08
    • 2018-07-15
    相关资源
    最近更新 更多