2017-03-29 73 views
0

我有一個監視系統返回JSON數據。我使用Powershell來獲取所有受監控的服務器及其屬性的子集。然後我想將這些屬性導出爲與XSD匹配的XML文件,但我不知道如何執行此操作。匹配Powershell XML輸出到模式

當我運行

$allServers | get-member 

我可以看到所有屬性用於在System.Management.Automation.PSCustomObject的服務器。所以,我跑:

$filtered = $allServers | Select-Object Id,HostName,Description,Status 

好吧,現在我有我想要的屬性,我可以運行這樣的事情:

$filtered = ($filtered | ConvertTo-Xml) 

,現在我有一個System.Xml.XmlDocument對象。超。我可以使用保存方法:

$filtered.Save("c:\test\test.xml") 

輸出看起來不錯,但與所需的模式文件不匹配。

<?xml version="1.0" encoding="utf-8"?> 
<Objects> 
    <Object Type="System.Management.Automation.PSCustomObject"> 
    <Property Name="id" Type="System.Int32">6</Property> 
    <Property Name="hostname" Type="System.String">server1</Property> 
    <Property Name="description" Type="System.String">dc</Property> 
    <Property Name="status" Type="System.Int32">1</Property> 
    </Object> 
</Objects> 

我的模式是這樣的:

<?xml version="1.0" encoding="Windows-1252"?> 
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified"> 
    <xsd:element name="ServerImport"> 
    <xsd:complexType> 
     <xsd:sequence> 
     <xsd:element name="Servers"> 
      <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element maxOccurs="unbounded" name="Server"> 
       <xsd:complexType> 
        <xsd:sequence> 
        <xsd:element name="Id" type="xsd:int" /> 
        <xsd:element name="HostName" type="xsd:string" /> 
        <xsd:element name="Description" type="xsd:string" /> 
        <xsd:element name="Status" type="xsd:int" /> 
        </xsd:sequence> 
       </xsd:complexType> 
       </xsd:element> 
      </xsd:sequence> 
      </xsd:complexType> 
     </xsd:element> 
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
</xs:schema> 

那麼,如何讓我的輸出相匹配的模式?

謝謝。

+0

好像您需要將Select-Object的輸出轉換爲定義的類。你使用的是什麼版本的Powershell? – Forty3

+0

我認爲目前運行我的任務的服務器有4個,但是我可以安裝5. – StackExchangeGuy

+0

如果你能找到一個v5環境,你可以嘗試將輸出轉換成一個類,然後把它寫入XML。純粹的理論,因爲我還沒有安裝v5。 – Forty3

回答

1

PowerShell v5支持正確的類結構。因此,你可以創建一個包含您想要的信息和小十歲上下的功能對類轉換爲一個XmlNode類:

function makeXML($parentNode, $class) { 

    $d = $parentNode.OwnerDocument.CreateElement($class.GetType().Name); 
    $class.psobject.properties | foreach { 
     $p = $doc.CreateElement($_.Name); 
     $p.InnerText = $_.Value; 
     $d.AppendChild($p); 
    } 

    $parentNode.AppendChild($d); 
} 

class Server { 
    [int]$Id; 
    [string]$HostName; 
    [string]$Description; 
    [int]$Status 
}; 

# Here you would need to convert the output from 
#  Select-Object ID,HostName,Description,Status 
# to instances of type Server 

$s = New-Object server; 
$s.Id = 1; 
$s.HostName = "localhost"; 
$s.Description = "Local Server"; 
$s.Status = 3; 

# Create the empty XML document to save your results to with root node of "Servers" 
$doc = New-Object System.Xml.XmlDocument; 
$doc.LoadXml("<ServerImport><Servers></Servers></ServerImport>"); 
$serversNode = $doc.SelectSingleNode("/ServerImport/Servers"); 

# This could likely be a pipe operation against your list of Server objects 
# $filtered | { makeXml $serversNode $_ } 
makeXML $serversNode $s; 
# Save your xml to a file 
$doc.Save("C:\test\test.xml"); 

導致下面的XML:

<ServerImport> 
    <Servers> 
    <Server> 
     <Id>1</Id> 
     <HostName>localhost</HostName> 
     <Description>Local Server</Description> 
     <Status>3</Status> 
    </Server> 
    </Servers> 
</ServerImport> 

注意:我確信有更優雅的解決方案,上面的代碼可能會有十幾個增強功能。但是,這應該讓你開始。

編輯 - 忽略了XML所需的結構(錯過了ServerImport根節點)。

+0

我結束了使用System.XMl.XmlTextWriter類,但我也喜歡你的答案。下次我肯定會記住這一點。謝謝。 – StackExchangeGuy