元素的Xpath与元素名称中的冒号

时间:2011-06-13 12:55:07

标签: c# xml xpath

我的xml是

<?xml version="1.0" encoding="utf-8"?>
<EntityDescriptor ID="_2d6175bd-f939-49f2-a980-db4179f32074" entityID="https://server1.domain.com:xx3/yyy/" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
  <RoleDescriptor xsi:type="fed:ApplicationServiceType" xmlns:fed="http://docs.oasis-open.org/wsfed/federation/200706" protocolSupportEnumeration="http://docs.oasis-open.org/wsfed/federation/200706" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <fed:ClaimTypesRequested>
      <auth:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity" Optional="true" xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
    </fed:ClaimTypesRequested>
    <fed:TargetScopes>
      <EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
        <Address>https://baarnntl1/</Address>
      </EndpointReference>
    </fed:TargetScopes>
    <fed:PassiveRequestorEndpoint>
      <EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
        <Address>https://baarnntl1/</Address>
      </EndpointReference>
    </fed:PassiveRequestorEndpoint>
  </RoleDescriptor>
</EntityDescriptor>

我想更改地址元素值

XmlDocument fedMetaDocument = new XmlDocument();
fedMetaDocument.Load(federatedMetadataFile);
XmlNamespaceManager mgr = new XmlNamespaceManager(fedMetaDocument.NameTable);
mgr.AddNamespace("fed", "http://docs.oasis-open.org/wsfed/federation/200706");

foreach (XmlNode targetScopeNode in fedMetaDocument.SelectNodes("TargetScopes/EndpointReference/Address", mgr))
{
    targetScopeNode.Value = tsakListUrl;
}
foreach (XmlNode PassiveRequestorEndpointNode in fedMetaDocument.SelectNodes("TargetScopes/EndpointReference/Address", mgr))
{
    PassiveRequestorEndpointNode.Value = tsakListUrl;
}

我收到错误

  System.Xml.XPath.XPathException was unhandled by user code
  Message=Expression must evaluate to a node-set.
  Source=System.Xml
  StackTrace:
       at MS.Internal.Xml.XPath.XPathParser.ParseNodeTest(AstNode qyInput, AxisType axisType, XPathNodeType nodeType)
       at MS.Internal.Xml.XPath.XPathParser.ParseStep(AstNode qyInput)
       at MS.Internal.Xml.XPath.XPathParser.ParseRelativeLocationPath(AstNode qyInput)

3 个答案:

答案 0 :(得分:3)

在选择应用了命名空间的节点时,XPath表达式应包含命名空间。 [参考文献]

所以XPath表达式应该是以下

//fed:TargetScope/EndpointReference/Address

而不是

//TargetScope/EndpointReference/Address

答案 1 :(得分:0)

也许这有帮助...尝试以下代码:

foreach (XmlNode targetScopeNode in fedMetaDocument.GetElementsByTagName("Address"))
{
  targetScopeNode.InnerText = tsakListUrl;
}

答案 2 :(得分:0)

除了

mgr.AddNamespace("fed", "http://docs.oasis-open.org/wsfed/federation/200706");

您需要声明默认命名空间的前缀:

mgr.AddNamespace("meta", "urn:oasis:names:tc:SAML:2.0:metadata");

然后在该命名空间中的所有元素上使用它:

fedMetaDocument.SelectNodes("fed:TargetScopes/meta:EndpointReference/meta:Address", mgr))

如果您不了解基础知识,那么命名空间就是其中之一,如果您尝试通过反复试验让它们工作,那么它真的会让您失望。请参阅this earlier answer of mine about the default namespace and XPath