【问题标题】:How to merge xml files with different elements/nodes into a single file using PowerShell如何使用 PowerShell 将具有不同元素/节点的 xml 文件合并到一个文件中
【发布时间】:2014-11-15 00:29:38
【问题描述】:

我正在尝试使用 PowerShell 将 3 个 xml 文件合并为 1 个。 我尝试了多种使用 Select-Xml、CreateElement 和 AppendChild 等的方法,但似乎无法理解如何将我想要正确包含到新 XML 文档中的元素。我要么得到一个空的结果文件,要么在节点中得到 System.Xml.Element。

这三个文件的内容是: 档案A

<?xml version="1.0" encoding="utf-8"?>
<ResourceResponse>
<Status>Success</Status>
 <Resource id="12345" name="aName" description="Microsoft Windows 2008" location="" instanceId="10003" typeId="1">
 <Agent id="23456" address="x.x.x.x" port="2144" version="x.x.x" unidirectional="false" />
 <Ip address="x.x.x.x" netmask="255.0.0.0" mac="00:00:00:00:00:00" />
 <Ip address="x.x.x.x" netmask="255.255.240.0" mac="00:50:56:03:40:E2" />
 <ResourceInfo key="fqdn" value="aName.here.lo" />
 </Resource>
</ResourceResponse>

文件 B

<?xml version="1.0" encoding="utf-8"?>
<ResourcePrototypeResponse>
<Status>Success</Status>
<ResourcePrototype instanceId='10164' resourceTypeId='3' id='10213' name='TCP Socket'/>
</ResourcePrototypeResponse>

文件 C

<?xml version="1.0" encoding="utf-8"?>
      <Resource name="SocketHTTP">
            <ResourceConfig key="hostname" value="localhost"/>
            <ResourceConfig key="port" value="80"/>
            <ResourceConfig key="sotimeout" value="10"/>
            <ResourceConfig key="service.log_track.enable" value="false"/>
            <ResourceConfig key="service.log_track.level" value="Error"/>
            <ResourceConfig key="service.log_track.include" value=""/>
            <ResourceConfig key="service.log_track.exclude" value=""/>
            <ResourceInfo key="autoIdentifier" value="SocketHTTP"/>
        </Resource>

我希望创建的文件看起来像:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CreateResourceRequest>
<Resource id="12345" name="aName" description="Microsoft Windows 2008" location="" instanceId="10087" typeId="1">
 <Agent id="23456" address="x.x.x.x" port="2144" version="x.x.x" unidirectional="false"/>
  <Ip address="x.x.x.x" netmask="255.255.255.0"/>
  <Ip address="x.x.x.x" netmask="255.0.0.0"/>
 <ResourceInfo key="fqdn" value="aName.here.lo"/>
 </Resource>
 <ResourcePrototype instanceId="10164" resourceTypeId="3" id="10213" name="TCP Socket"/>
      <Resource name="SocketHTTP">
            <ResourceConfig key="hostname" value="target.here.lo"/>
            <ResourceConfig key="port" value="80"/>
            <ResourceConfig key="sotimeout" value="10"/>
            <ResourceConfig key="service.log_track.enable" value="false"/>
            <ResourceConfig key="service.log_track.level" value="Error"/>
            <ResourceConfig key="service.log_track.include" value=""/>
            <ResourceConfig key="service.log_track.exclude" value=""/>
            <ResourceInfo key="autoIdentifier" value="SocketHTTP"/>
        </Resource>

</CreateResourceRequest>

提前谢谢,我很难过....

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

    你需要这样的东西:

    function Add-XmlFromFile ([String]$Path,
                              [String]$XPath,
                              [System.Xml.XmlElement]$ParentElement) {
    
        [System.Xml.XmlElement]$ChildElement = `
            (Select-Xml -Path $Path -XPath $XPath).Node
    
        [System.Xml.XmlElement]$ImportedElement = `
            $ParentElement.OwnerDocument.ImportNode($ChildElement, $true)
    
        return $ParentElement.AppendChild($ImportedElement)
    }
    
    # Creating new XML object.
    $Xml = New-Object Xml
    $XmlDeclaration = $Xml.CreateXmlDeclaration("1.0", "UTF-8", $null)
    $Xml.AppendChild($XmlDeclaration) | Out-Null
    
    # Creating parent element.
    $CreateResourceRequest = $Xml.CreateElement("CreateResourceRequest")
    
    # Adding child elements to parent.
    Add-XmlFromFile -Path "File A.xml" `
        -XPath "//ResourceResponse/Resource" `
        -ParentElement $CreateResourceRequest | Out-Null
    Add-XmlFromFile -Path "File B.xml" `
        -XPath "//ResourcePrototypeResponse/ResourcePrototype" `
        -ParentElement $CreateResourceRequest | Out-Null
    Add-XmlFromFile -Path "File C.xml" `
        -XPath "//Resource" `
        -ParentElement $CreateResourceRequest | Out-Null
    
    # Appending parent to XML object.
    $Xml.AppendChild($CreateResourceRequest) | Out-Null
    
    # Saving XML object.
    $Xml.OuterXml | Out-File -FilePath "File D.xml" -Encoding "UTF8"
    

    【讨论】:

    • 完美运行!不仅如此,而且我知道对它的理解要好一些。希望我能早点问...再次感谢。
    • 如此接近.....我看到 $Xml.AppendChild($XmlDeclaration) |写入文件时,Out-Null 在 '\我没有正确设置吗?
    • 已添加 -Encoding "UTF8" - 实际上 PS 默认使用 UCS-2 Little Endian 编码。但是,无论是使用 UCS-2 还是使用 UTF-8,我都无法重现该问题(在 PS 2.0 中) - 我在我的代码生成的文件中看不到任何其他字符。
    • 谢谢亚历山大。我正在使用 PS4(在升级到超出标题周围的 PS3 Invoke-RestMethod 错误之后)。我还添加了 -Encoding uft8 开关,因为有效负载最终为 Unicode,我需要纯文本。这似乎是文件写入方式的产物。我找到了一些有关导致此问题的流编码的信息。我使用十六进制编辑器和 tcpdump 确认了文件中的数据。我决定直接编写有效载荷而不是先保存它。 (应该一直这样做!)再次感谢您的快速回复!
    猜你喜欢
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多