C# XDocument获取定义它的元素';s自己的命名空间

C# XDocument获取定义它的元素';s自己的命名空间,c#,xml,windows-10-mobile,C#,Xml,Windows 10 Mobile,正如问题所述。我有一个xml文档(如下所示),需要获取定义名称空间urn:schemas sony com:av的X_ScalarWebApi_DeviceInfo。不幸的是,它导致了一个错误:{System.NullReferenceException:Object reference未设置为对象的实例。我主要对ServiceList元素感兴趣,但它不起作用。平台-Windows 10 mobile。 有什么想法吗 <?xml version="1.0"?> <roo

正如问题所述。我有一个xml文档(如下所示),需要获取定义名称空间urn:schemas sony com:av的X_ScalarWebApi_DeviceInfo。不幸的是,它导致了一个错误:
{System.NullReferenceException:Object reference未设置为对象的实例
。我主要对ServiceList元素感兴趣,但它不起作用。平台-Windows 10 mobile。 有什么想法吗

<?xml version="1.0"?>
    <root xmlns="urn:schemas-upnp-org:device-1-0">    
        <specVersion>
            <major>1</major>
            <minor>0</minor>
        </specVersion>    
        <device>
            <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
            <friendlyName>ILCE-6000</friendlyName>
            <manufacturer>Sony Corporation</manufacturer>
            <manufacturerURL>http://www.sony.net/</manufacturerURL>
            <modelDescription>SonyDigitalMediaServer</modelDescription>
            <modelName>SonyImagingDevice</modelName>
            <UDN>uuid:000000001000-1010-8000-62F1894EE7BE</UDN>    
            <serviceList>
               <service>
                   <serviceType>urn:schemas-sony-com:service:ScalarWebAPI:1</serviceType>
                   <serviceId>urn:schemas-sony-com:serviceId:ScalarWebAPI</serviceId>
                   <SCPDURL/>
                   <controlURL/>
                   <eventSubURL/>
               </service>
            </serviceList>
            <av:X_ScalarWebAPI_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
                <av:X_ScalarWebAPI_Version>1.0</av:X_ScalarWebAPI_Version>
                <av:X_ScalarWebAPI_ServiceList>
                    <av:X_ScalarWebAPI_Service>
                        <av:X_ScalarWebAPI_ServiceType>guide</av:X_ScalarWebAPI_ServiceType>
                        <av:X_ScalarWebAPI_ActionList_URL>http://192.168.122.1:8080/sony</av:X_ScalarWebAPI_ActionList_URL>
                        <av:X_ScalarWebAPI_AccessType/>
                    </av:X_ScalarWebAPI_Service>
                    <av:X_ScalarWebAPI_Service>
                        <av:X_ScalarWebAPI_ServiceType>accessControl</av:X_ScalarWebAPI_ServiceType>
                        <av:X_ScalarWebAPI_ActionList_URL>http://192.168.122.1:8080/sony</av:X_ScalarWebAPI_ActionList_URL>
                        <av:X_ScalarWebAPI_AccessType/>
                    </av:X_ScalarWebAPI_Service>
                    <av:X_ScalarWebAPI_Service>
                        <av:X_ScalarWebAPI_ServiceType>camera</av:X_ScalarWebAPI_ServiceType>
                        <av:X_ScalarWebAPI_ActionList_URL>http://192.168.122.1:8080/sony</av:X_ScalarWebAPI_ActionList_URL>
                        <av:X_ScalarWebAPI_AccessType/>
                    </av:X_ScalarWebAPI_Service>
                </av:X_ScalarWebAPI_ServiceList>
            </av:X_ScalarWebAPI_DeviceInfo>
        </device>
    </root>

1.
0
urn:schemas upnp组织:设备:基本:1
ILCE-6000
索尼公司
http://www.sony.net/
SonyDigitalMediaServer
Sonyimaging设备
uuid:00000000 1000-1010-8000-62F1894EE7BE
urn:com:service:ScalarWebAPI:1
urn:com:serviceId:ScalarWebAPI
1
指导
http://192.168.122.1:8080/sony
访问控制
http://192.168.122.1:8080/sony
照相机
http://192.168.122.1:8080/sony
啊,代码:

XDocument xDoc = XDocument.Parse(xml_text);
//var av = xDoc.Root.GetDefaultNamespace();//.Attribute("xmlns");//
XNamespace av = "urn:schemas-sony-com:av";
System.Diagnostics.Debug.WriteLine(av);
<XElement> api_list = (List<XElement>)xDoc.Element(av + "X_ScalarWebAPI_DeviceInfo").Elements();
XDocument xDoc=XDocument.Parse(xml\u text);
//var av=xDoc.Root.GetDefaultNamespace();/.Attribute(“xmlns”)//
XNamespace av=“urn:com:av”;
系统.诊断.调试.写线(av);
api_list=(list)xDoc.Element(av+“X_ScalarWebAPI_DeviceInfo”).Elements();
==编辑== 嗯,两种解决方案都是可以的,所以我对其中一个进行投票,并将另一个作为答案:P
有人提到,仅使用“本地名称”的解决方案可能会导致搜索结果出现误报,因此为了安全起见,我使用的是第一个。感谢帮助!

元素
仅返回当前节点正下方的元素。您需要指定整个路径(注意有多个名称空间):

使用Xml-Linq

XDocument doc = XDocument.Load(FILENAME);
XElement x_ScalarWebAPI_DeviceInfo = doc.Descendants().Where(x => x.Name.LocalName == "X_ScalarWebAPI_DeviceInfo").FirstOrDefault();
XNamespace ns = x_ScalarWebAPI_DeviceInfo.Name.Namespace;

问题确实是Element或Elements方法只搜索直接的子元素。您可以使用Decentants(),但您将获得一个集合,因此您必须首先(表达式)创建一个集合

但是在表达式中,可以使用.Name.LocalName跳过整个名称空间,只查找元素的名称

关于这个问题:

XDocument xDoc = XDocument.Parse(xml_text);
XElement x_ScalarWebAPI_DeviceInfo = doc.Descendants().First(x.Name.LocalName == "X_ScalarWebAPI_DeviceInfo");

产生错误的代码在哪里?我忘记了,到ad,,现在它在;)正如你所看到的,我尝试了许多在Internet上看到的选项您的
xDoc
只有一个子元素
,所以调用
.element(av+“X_ScalarWebAPI\u DeviceInfo”)
return
null
。在以后的问题中,请尝试清理并格式化您的xml。Visual studio做得很好。某些行上的
-
令人困惑。实际上,这是VisualStudio的xml visualiser的输出,所以不,它做得不好:P我会马上格式化它,详细说明原因吗?我喜欢这个解决方案,是吗有点…清楚。最好假设我们不知道XML的确切结构,但我们可以确定有一个名为uv:X_ScalarWebApi_DeviceInfo的元素及其结构(仅是它的后代)。您确定ns+“device”吗?设备定义为并且没有名称空间,所以可以将其添加到元素()中吗调用?我今天无法检查它,但我会检查它以及其他解决方案。是的,名称空间是继承的。请尝试一下。那么当有两个名称空间时会发生什么?是否附加/覆盖了它?我可以看到,对于定义了不同XMLN的子代节点,您只使用了第二个名称空间。当它们引用sa时会被覆盖me
xmlns
。您也可以在任何元素上使用多个名称空间,例如
xmlns:av=“…”
,但是这些元素必须在XML中限定(
av:X\u ScalarWebAPI
)。但是如果需要检索元素的属性,则不应应用名称空间!
XDocument xDoc = XDocument.Parse(xml_text);
XElement x_ScalarWebAPI_DeviceInfo = doc.Descendants().First(x.Name.LocalName == "X_ScalarWebAPI_DeviceInfo");