c# - 为什么这个 XPath 表达式适用于一个节点而不适用于另一个节点?
问题描述
我有一个函数可以检索.InnerText
XML 节点中的属性:
string getPropertyFromNode_string(XmlNode node, string propertyName)
{
try
{
string selectString = "./empty:content/m:properties/d:";
return node.SelectSingleNode(selectString + propertyName, Utils.nmREST).InnerText;
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
throw exception;
}
}
nmREST
在静态类的构造函数中定义Utils
如下:
public static XmlNamespaceManager nmREST = new XmlNamespaceManager(new NameTable());
static Utils()
{
nmREST.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
nmREST.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
nmREST.AddNamespace("empty", "http://www.w3.org/2005/Atom");
nmREST.AddNamespace("z", "#RowsetSchema");
}
我在这个 XmlNode 上测试函数:
<entry m:etag=""81"" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<id>Web/Lists(guid'someguid')/Items(1213)</id>
<category term="SP.Data.LibItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="Web/Lists(guid'someguid')/Items(1213)" />
<title />
<updated>2019-04-16T06:16:50Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Int32" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">1213</d:Id>
<d:FileLeafRef xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">myfile.xlsm</d:FileLeafRef>
<d:FeatureCount m:type="Edm.Double" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">33</d:FeatureCount>
<d:Status xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">Production Ready</d:Status>
<d:CheckoutUserId m:null="true" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" />
<d:EditorId m:type="Edm.Int32" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">25</d:EditorId>
<d:ID m:type="Edm.Int32" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">1213</d:ID>
</m:properties>
</content>
</entry>
使用此函数调用:
getPropertyFromNode_string(thisNode,"ID")
1213
并且成功检索到该值。
但是,当我在以下 XmlNode 上对其进行测试时:
<entry m:etag=""24"" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<id>Web/Lists(guid'someguid')/Items(1422)</id>
<category term="SP.Data.LibItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="Web/Lists(guid'someguid')/Items(1422)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Station" type="application/atom+xml;type=entry" title="Station" href="Web/Lists(guid'someguid')/Items(1422)/Station">
<m:inline>
<entry>
<id>anotherguid</id>
<category term="SP.Data.DifferentLibItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<title />
<updated>2019-04-16T05:58:17Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:FacilityNumber xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">1068</d:FacilityNumber>
</m:properties>
</content>
</entry>
</m:inline>
</link>
<title />
<updated>2019-04-16T05:58:17Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:FileLeafRef xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">thatfilename.xlsm</d:FileLeafRef>
<d:Title m:null="true" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" />
</m:properties>
</content>
</entry>
使用函数调用:
getPropertyFromNode_string(thisNode,"FacilityNumber")
然后SelectSingleNode()
调用会引发异常并显示以下消息:
Object reference not set to an instance of an object.
我猜这意味着 XPath 表达式没有成功定位<d:FacilityNumber>
元素,所以没有对象可以获取InnerText
。为什么找不到元素?第二个节点的 XML 结构有什么不同,我应该改用什么 XPath 表达式?
解决方案
根据 Laurent Lequenne 对 OP 的评论,包括 XPath 表达式中子节点的完整嵌套序列成功检索到所需的子节点,如下所示:
./empty:link/m:inline/empty:entry/empty:content/m:properties/d:
推荐阅读
- node.js - 在同一个域(cpanel)上托管 angular 和 nodejs
- firebase - 在flutter firebase中调用了方法'[]'的空错误
- php - 如何解决,找不到模块“@nesk/rialto”错误
- android - 我想在关闭插页式广告时播放媒体。不是以前
- java - 使用 spring-messaging 自动映射 websocket 消息
- react-native - 存储与用户帐户相关的访问令牌
- ios - 为什么 stride 函数在 Swift 中会这样工作?
- mysql - 如何通过单击图标按钮使用 Angular NodeJS 和 Mysql 更新状态
- node.js - 如果提供了授权标头,则无法访问部署在 AWS Beanstalk Node.js 上的 Apollo Server
- python - 将单个链接列表转换为循环并验证