我有一个返回JSON数据的监控系统。我使用Powershell来获取所有受监视的服务器及其属性的子集。然后我想将这些属性导出到与XSD匹配的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 :(得分:1)
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根节点)。