【问题标题】:Errors on converting XML to an object using XPath使用 XPath 将 XML 转换为对象时出错
【发布时间】:2020-08-06 17:00:53
【问题描述】:

我在 Powershell、XML 和 XPath 上苦苦挣扎。

我想要一个脚本,它可以读取文件、提取我需要的节点并转换为我可以在脚本中使用的对象。

文件如下:

<?xml version="1.0"?>
<Objs xmlns="http://schemas.microsoft.com/powershell/2004/04" Version="1.1.0.1">
    <Obj RefId="0">
        <TN RefId="0">
            <T>System.Object</T>
        </TN>
        <Props>
            <Obj N="Set1" RefId="1">
                <TN RefId="1">
                    <T>System.Object</T>
                </TN>
                <Props>
                    <S N="Folder">C:\t1</S>
                    <Obj N="Configs" RefId="10">
                        <TN RefId="10">
                            <T>System.Object</T>
                        </TN>
                        <Props>
                            <S N="N1">Geralt</S>
                            <S N="N2">Ciri</S>
                        </Props>
                    </Obj>
                </Props>
            </Obj>
            <Obj N="Set2" RefId="2">
                <TN RefId="2">
                    <T>System.Object</T>
                </TN>
                <Props>
                    <S N="Folder">C:\t2</S>
                    <Obj N="Configs" RefId="20">
                        <TN RefId="20">
                            <T>System.Object</T>
                        </TN>
                        <Props>
                            <S N="N1">Triss</S>
                            <S N="N2">Yen</S>
                        </Props>
                    </Obj>
                </Props>
            </Obj>
        </Props>
    </Obj>
</Objs>

我写了这段代码:

$path = "c:\file.xml"
$xpath = "/ns:Objs/ns:Obj/ns:Props/ns:Obj[@N='Set2']"
$ns = "@{ns='http://schemas.microsoft.com/powershell/2004/04'}"

[xml]$apps = Select-Xml -Path $path -XPath $xpath -Namespace $ns

我期待能够写作:

Write-Host "文件夹是:$apps.Folder" -> C:\t1 Write-Host "Config is: $apps.Configs.N2" -> Yen

但由于这个错误,我无法获取对象:

Cannot convert value "...". Error: "This document already has a 'DocumentElement' node."
At line:1 char:1
+ [xml]$t = Select-Xml -Path $path -XPath "/ns:Objs/ns:Obj/ns:Props/ns:Obj[@N='Set2']"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

有什么建议吗?

【问题讨论】:

    标签: powershell select-xml


    【解决方案1】:

    这看起来像是来自Export-CliXml 的输出。使用Import-CliXml反序列化会更容易:

    $apps = Import-Clixml -Path c:\file.xml
    $apps.Set2.Folder
    $apps.Set2.Configs.N2
    

    在您的原始代码中,命名空间的语法错误。它应该是一个哈希表。

    $ns = @{ns='http://schemas.microsoft.com/powershell/2004/04'}
    

    用双引号将哈希表代码括起来会创建一个字符串。如果我们将您的 XPATH 表达式用于包含 Set2Obj 节点,您将需要进一步深入节点树。

    $path = "c:\file.xml"
    $xpath = "/ns:Objs/ns:Obj/ns:Props/ns:Obj[@N='Set2']"
    $ns = @{ns='http://schemas.microsoft.com/powershell/2004/04'}
    
    $apps = Select-Xml -Path $path -XPath $xpath -Namespace $ns
    $apps.Node.Props.S.Innertext # Folder value
    $apps.Node.Props.Obj.Props.S.Innertext # Configs values
    

    【讨论】:

    • 我需要使用 XPath 作为我在示例中搜索的值“Set2”,这将是 Azure 管道中的一个变量,我还需要根据一个变量选择 N1 或 N2...要么我留在 XPath,我猜我每次需要基于变量查找数据时都需要一个不同的 XPath。似乎不太容易阅读,所以我将尝试使用 Import-Clixml 和循环。再次感谢,我学到了新东西!!
    猜你喜欢
    • 2011-12-10
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 2011-03-11
    相关资源
    最近更新 更多