gpt4 book ai didi

xml - 具有命名空间的 PowerShell XML 选择节点

转载 作者:行者123 更新时间:2023-12-03 17:21:45 25 4
gpt4 key购买 nike

我尝试从 XML 文件中选择节点,但遇到了似乎由命名空间引起的问题。

下面的代码不返回任何内容。但是如果我从 XML 文件中删除命名空间,我就会得到预期的结果。

MWE

$StandaloneXML = "test.xml"
# Load XML content
$NewStandaloneXML = New-Object -TypeName "System.XML.XMLDocument"
$NewStandaloneXML.Load($StandaloneXML)
# Get namespace
$Namespace = New-Object -TypeName "Xml.XmlNamespaceManager" -ArgumentList $NewStandaloneXML.NameTable
$Namespace.AddNamespace("jboss", $NewStandaloneXML.DocumentElement.NamespaceURI)
$NewStandaloneXML.SelectNodes("jboss:server/interfaces/interface", $Namespace)

XML

<?xml version="1.0" ?>
<server xmlns="urn:jboss:domain:4.2">
<interfaces>
<interface name="management">
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
</interfaces>
</server>

预期输出

name       inet-address----       ------------management inet-addresspublic     inet-address

最佳答案

正如 @AnsgarWiechers 所说,每个节点都必须以其 namespace 为前缀,因为没有继承。

MWE

$StandaloneXML = "test.xml"
# Load XML content
$NewStandaloneXML = New-Object -TypeName "System.XML.XMLDocument"
$NewStandaloneXML.Load($StandaloneXML)
# Get namespace
$Namespace = New-Object -TypeName "Xml.XmlNamespaceManager" -ArgumentList $NewStandaloneXML.NameTable
$Namespace.AddNamespace("jboss", $NewStandaloneXML.DocumentElement.NamespaceURI)
$NewStandaloneXML.SelectNodes("jboss:server/jboss:interfaces/jboss:interface", $Namespace)

为了让事情变得更容易,我构建了一个小函数来自动为所提供的 XPath 中的每个节点添加前缀。

function Select-XMLNode {
[CmdletBinding()]
Param (
[Parameter (
Position = 1,
Mandatory = $true,
HelpMessage = "XML content"
)]
[ValidateNotNullOrEmpty()]
[System.XML.XMLDocument]
$XML,
[Parameter (
Position = 2,
Mandatory = $true,
HelpMessage = "XPath corresponding to the node"
)]
[ValidateNotNullOrEmpty()]
[String]
$XPath,
[Parameter (
Position = 3,
Mandatory = $false,
HelpMessage = "Namespace"
)]
[ValidateNotNullOrEmpty()]
[String]
$Namespace = $XML.DocumentElement.NamespaceURI
)
Begin {
# Variables
$Delimiter = "/"
$Alias = "x"
$SpecialCharacters = [RegEx]::New('^[/.@]*')
if ($XPath -match $SpecialCharacters) {
$Prefix = $Matches[0]
$XPath = $XPath -replace $SpecialCharacters, ''
}
}
Process {
# Get namespace
$NamespaceManager = New-Object -TypeName "Xml.XmlNamespaceManager" -ArgumentList $XML.NameTable
$NamespaceManager.AddNamespace($Alias, $Namespace)
# Split XPath to identify nodes
$Nodes = $XPath.Split($Delimiter)
$PrefixedNodes = New-Object -TypeName "System.Collections.ArrayList"
# Prefix nodes with namespace (alias)
foreach($Node in $Nodes) {
if ($Node) {
[Void]$PrefixedNodes.Add("${Alias}:${Node}")
}
}
# Join prefixed-nodes to create new XPath with namespace
$XPathWithNamespace = $PrefixedNodes -join $Delimiter
# Check XPath prefix
if ($Prefix) {
$XPathWithNamespace = $Prefix + "" + $XPathWithNamespace
}
# Select and return nodes
$SelectedNodes = $XML.SelectNodes($XPathWithNamespace, $NamespaceManager)
return $SelectedNodes
}
}

关于xml - 具有命名空间的 PowerShell XML 选择节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54352461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com