我正在尝试找到节点" PermissionSet"在以下XML中。我对XPath不太熟悉,所以我试图走树去到我想要的节点。
我像这样加载XML:
var reader = new XmlTextReader(manifestFilename)
XNamespace _manifestNamespace = "urn:schemas-microsoft-com:asm.v1";
_appManifest = XElement.Load(reader);
var node1 = _appManifest.Elements(_manifestNamespace + "trustInfo").FirstOrDefault();
var node2 = node1.Elements(_manifestNamespace + "security").FirstOrDefault();
var node3 = node2.Elements(_manifestNamespace + "applicationRequestMinimum").FirstOrDefault();
var node4 = node3.Elements(_manifestNamespace + "PermissionSet").FirstOrDefault();
我的第一个节点一直空着。我怀疑我使用的命名空间是错误的,但我不知道该使用什么。这是XML:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel node will disable file and registry virtualization.
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" />
</applicationRequestMinimum>
</security>
</trustInfo>
</asmv1:assembly>
答案 0 :(得分:0)
xmlns="urn:schemas-microsoft-com:asm.v2"
xmlns=
属性声明了一个默认命名空间,它适用于从它出现的元素开始的所有非前缀元素,并“继承”到其所有后代,直到并且除非出现另一个xmlns=
属性设置不同的默认值(或将默认值设置为no-namespace,如果值为""
)。
请注意,默认命名空间仅适用于元素。除非属性名称包含名称空间前缀,否则属性永远不会被命名空间。
答案 1 :(得分:0)
<PermissionSet>
元素驻留在此命名空间中:“urn:schemas-microsoft-com:asm.v2”。这是继承自它的祖先<trustInfo>
元素:
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
........
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" />
........
</trustInfo>
所以你可以通过这种方式获得<PermissionSet>
元素:
XNamespace v2 = "urn:schemas-microsoft-com:asm.v2";
var result = _appManifest.Root
.Element(v2 + "trustInfo")
.Element(v2 + "security")
.Element(v2 + "applicationRequestMinimum")
.Element(v2 + "PermissionSet");
更新:
你的评论是对的,如果缺少任何元素(除了最后一个元素,PermissionSet),我的代码将抛出空引用异常。但这不是这个答案的重点,只是为了简单起见。无论如何,更清洁的方法来避免这种异常恕我直言,正在使用XPath查询:
var nsManager = new XmlNamespaceManager(new NameTable());
nsManager.AddNamespace("v2", "urn:schemas-microsoft-com:asm.v2");
var result = _appManifest
.Root
.XPathSelectElement(
"./v2:trustInfo/v2:security/v2:applicationRequestMinimum/v2:PermissionSet"
, nsManager);
XPathSelectElement()
更强大,可以处理不受控制的XML结构。无论丢失什么元素/属性,它都不会抛出异常。如果没有元素与XPath参数匹配,冷静地会返回null
。