How to iterate XML values with Powershell and filter by key name?

huangapple go评论88阅读模式
英文:

How to iterate XML values with Powershell and filter by key name?

问题

我有一些看起来像这样的 XML:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<FlowInstance xmlns="http://www.oeplatform.org/version/2.0/schemas/flowinstance"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oeplatform.org/version/2.0/schemas/flowinstance schema-1161.xsd">
    <Values>
        <donotoutput>
            <Name><![CDATA[donotoutput]]></Name>
            <Value><![CDATA[donotoutput value]]></Value>
        </donotoutput>
        <specifics_test1>
            <Name><![CDATA[Test1]]></Name>
            <Value>Val1</Value>
            <Value>Val2</Value>
            <Value>Val3</Value>
        </specifics_test1>
        <specifics_test2>
            <Name><![CDATA[Test2]]></Name>
            <Value><![CDATA[Test2 value]]></Value>
        </specifics_test2>
        <specifics_test3>
            <Name><![CDATA[Test3]]></Name>
            <Value><![CDATA[Test3 value]]></Value>
        </specifics_test3>
    </Values>
</FlowInstance>

我想要遍历其中的 <Values> 部分,但只想处理键以 "specifics_" 开头的部分,我该如何做到?

我尝试了以下 PowerShell 代码:

[xml]$xml = Get-Content -Path "C:\Temp\xml\xml_cleaned.xml"

$xml.FlowInstance.Values
$xml.FlowInstance.Values.specifics_test1

这样可以给我键和值,但我无法像这样使用循环:

foreach ($val in $xml.FlowInstance.Values){
    $val
}

我还想获取键,只解析以 "specifics_" 开头的键,但我无法像在 PowerShell 中使用哈希表那样使用 .Keys,在这个 XML 中我该如何做到?

英文:

I have som XML that looks like this

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<FlowInstance xmlns="http://www.oeplatform.org/version/2.0/schemas/flowinstance"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oeplatform.org/version/2.0/schemas/flowinstance schema-1161.xsd">
    <Values>
        <donotoutput>
            <Name><![CDATA[donotoutput]]></Name>
            <Value><![CDATA[donotoutput value]]></Value>
        </donotoutput>
        <specifics_test1>
            <Name><![CDATA[Test1]]></Name>
            <Value>Val1</Value>
            <Value>Val2</Value>
            <Value>Val3</Value>
        </specifics_test1>
        <specifics_test2>
            <Name><![CDATA[Test2]]></Name>
            <Value><![CDATA[Test2 value]]></Value>
        </specifics_test2>
        <specifics_test3>
            <Name><![CDATA[Test3]]></Name>
            <Value><![CDATA[Test3 value]]></Value>
        </specifics_test3>
    </Values>
</FlowInstance>

and i want to iterate over the <Values> part of it but only the ones that the key start with "specifics_", how can i do that?

Ive tried this Powershell code

[xml]$xml = Get-Content -Path "C:\Temp\xml\xml_cleaned.xml"

$xml.FlowInstance.Values
$xml.FlowInstance.Values.specifics_test1

gives me the keys and values, but i cant do a loop like this

foreach ($val in $xml.FlowInstance.Values){
    $val
}

and i would also like to get the keys to only parse the ones with "specifics_*" but i cant to that like an hashtable in Powershell with .Keys, how would i do that with this XML?

答案1

得分: 3

由于你正在处理 XML,一种方法是使用 XML 解析器:

# 首先,声明命名空间
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("xx", "http://www.oeplatform.org/version/2.0/schemas/flowinstance")
# 注意,这里的 "xx" 只是默认命名空间的别名

# 然后,遍历它们:
$values = $xml.SelectNodes('//xx:*[starts-with(name(),"specifics_")]/xx:Value',$ns);
foreach ($value in $values){
   echo $value
}

以上代码使用 PowerShell 编写,它首先声明了命名空间,并使用 XML 解析器遍历了 XML 中以 "specifics_" 开头的元素的值。

英文:

Since you are dealing with xml, one way to do it is use an xml parser:

#first, declare namespaces
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("xx", "http://www.oeplatform.org/version/2.0/schemas/flowinstance")
#note "xx" here is just a nickname for the default namespace

#and now just iterate over them:
$values = $xml.SelectNodes('//xx:*[starts-with(name(),"specifics_")]/xx:Value',$ns);
foreach ($value in $values){
   echo $value
 }

答案2

得分: 0

Jack Fleeting的回答帮助了我,指导了我正确的方向并解决了我的问题。我希望在循环中也包含键,所以最终得到了以下代码:

# 加载XML内容
[xml]$xml = Get-Content -Path "C:\Temp\xml\xml_cleaned.xml"

# 定义XML中使用的命名空间
$ns = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", "http://www.oeplatform.org/version/2.0/schemas/flowinstance")

# 遍历Values元素
$valuesElements = $xml.SelectNodes("//ns:FlowInstance/ns:Values/ns:*[starts-with(name(),'specifics_')]", $ns)
foreach ($element in $valuesElements) {
    $keyName = $element.LocalName
    $name = $element.SelectSingleNode("ns:Name", $ns).InnerText
    $value = if ($element.SelectNodes("ns:Value", $ns).Count -eq 1) {
        $element.SelectNodes("ns:Value", $ns).InnerText
    } else {
        $element.SelectNodes("ns:Value", $ns) | ForEach-Object { $_.InnerText }
    }

    Write-Host "键名: $keyName"
    Write-Host "名称: $name"
    Write-Host "值: $value"
    Write-Host "-----------"
}

希望对你有帮助!

英文:

Jack Fleeting's answer above helped me in the right direction and answered my problem. I wanted the key in my loop aswell so i ended up with the following code

# Load the XML content
[xml]$xml = Get-Content -Path "C:\Temp\xml\xml_cleaned.xml"

# Define the namespace used in the XML
$ns = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", "http://www.oeplatform.org/version/2.0/schemas/flowinstance")

# Iterate over the Values elements
$valuesElements = $xml.SelectNodes("//ns:FlowInstance/ns:Values/ns:*[starts-with(name(),'specifics_')]", $ns)
foreach ($element in $valuesElements) {
    $keyName = $element.LocalName
    $name = $element.SelectSingleNode("ns:Name", $ns).InnerText
    $value = if ($element.SelectNodes("ns:Value", $ns).Count -eq 1) {
        $element.SelectNodes("ns:Value", $ns).InnerText
    } else {
        $element.SelectNodes("ns:Value", $ns) | ForEach-Object { $_.InnerText }
    }

    Write-Host "Key Name: $keyName"
    Write-Host "Name: $name"
    Write-Host "Value(s): $value"
    Write-Host "-----------"
}

huangapple
  • 本文由 发表于 2023年7月27日 17:39:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76778429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定