建立自定义 XML 文件

Posted

技术标签:

【中文标题】建立自定义 XML 文件【英文标题】:Build up custom XML-File 【发布时间】:2017-02-23 15:32:06 【问题描述】:

我需要一些帮助来使用 Powershell 构建 XML 文件。我以前从未这样做过。

一开始我觉得很幸运并尝试了“Export-Clixml”,但它并没有产生我想要的输出。我需要干净的 XML。

我有一个现有的 XML 文件,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
  <Settings>
    ...
  </Settings>
</DeploymentScript>

我从 XML 中读出设置并在 Powershell 中做一些事情。我创建了一个对象,如下所示:

TaskSequenceNumber TaskSequenceName
------------------ ----------------
0 01_Base
1 02_XA

我想将此对象保存在我的 XML 文件中。 (附加) XML 文件最终应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
  <Settings>
    ...
  </Settings>
  <Deploy>
    <SequenceData>
      <TaskSequenceNumber>1</TaskSequenceNumber>
      <TaskSequenceName>01_Base</TaskSequenceName>
    </SequenceData>
    <SequenceData>
      <TaskSequenceNumber>2</TaskSequenceNumber>
      <TaskSequenceName>02_XA</TaskSequenceName>
    </SequenceData>
  </Deploy>
</DeploymentScript>

我尝试了一些 .NET XML 方法,但没有得到结果。 有人能给我举个例子吗?

.

编辑: 感谢“Frode F.”!这里是最新的代码:

$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
  <Settings>
    ...
  </Settings>
</DeploymentScript>
"@

#$xml = [xml]( Get-Content -Path "$env:USERPROFILE\Desktop\Deploy-Settings.xml" )
$TaskSequences = [pscustomobject]@TaskSequenceNumber=0;TaskSequenceName="01_Base",[pscustomobject]@TaskSequenceNumber=1;TaskSequenceName="02_XA"

#Add Deploy-node
$DeployNode = $xml.CreateElement( "Deploy" )
$xml.DeploymentScript.AppendChild( $DeployNode ) > $null

foreach ( $element in $TaskSequences ) 

    $SeqDataNode = ([xml]@"
<SequenceData>
    <TaskSequenceNumber>$($element.TaskSequenceNumber + 1)</TaskSequenceNumber>
    <TaskSequenceName>$($element.TaskSequenceName)</TaskSequenceName>
</SequenceData>
"@).FirstChild

    #Add to Deploy-node
    $DeployNode.AppendChild( $xml.ImportNode( $SeqDataNode,$true ) ) > $null



$xml.Save( "$env:USERPROFILE\Desktop\Test.xml" )

【问题讨论】:

您确定架构吗?多个根节点会产生错误。你需要把设置和部署放在里面 很抱歉,我没有太多使用 XML 的经验。使用 XML-Notepad 创建了示例。我已经更新了提到的 XML。希望现在可以了。 下一次,包含您尝试过但不起作用的代码,以便我们帮助您修复您的代码 【参考方案1】:

您可以通过在 .NET 中使用 xml-classes 来尝试这样的事情:

#SampleInput
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<Settings>
  ...
</Settings>
"@

$TaskSequences = [pscustomobject]@TaskSequenceNumber=0;TaskSequenceName="01_Base",[pscustomobject]@TaskSequenceNumber=1;TaskSequenceName="02_XA"

#$xml = [xml](Get-Content -Path InputFile.xml)
#$TaskSequences = Get-RealDataFromSomeWhere

#Create new xml and remove root node
$newxml = $xml.Clone()
$newxml.RemoveChild($newxml.SelectSingleNode("/Settings")) > $null

#Add new DeploymentScript root-node with copy of Settings
$DeploymentScriptNode = $newxml.CreateElement("DeploymentScript")
$DeploymentScriptNode.AppendChild($newxml.ImportNode($xml.SelectSingleNode("/Settings"),$true)) > $null
$newxml.AppendChild($DeploymentScriptNode) > $null

#Add Deploy-node
$DeployNode = $newxml.CreateElement("Deploy")
$DeploymentScriptNode.AppendChild($DeployNode) > $null

foreach ($ts in $TaskSequences) 
    #Create SequenceData-element per TS
    $SeqDataNode = $newxml.CreateElement("SequenceData")

    $SeqDataNode.AppendChild($newxml.CreateElement("TaskSequenceNumber")) > $null
    $SeqDataNode.AppendChild($newxml.CreateElement("TaskSequenceName")) > $null

    $SeqDataNode.TaskSequenceNumber = "$($ts.TaskSequenceNumber + 1)"
    $SeqDataNode.TaskSequenceName = $ts.TaskSequenceName

    #Add to Deploy-node
    $DeployNode.AppendChild($SeqDataNode) > $null


$newxml.Save("$env:USERPROFILE\Desktop\Test.xml")

或者凌乱但更短的字符串方法:

#SampleInput
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<Settings>
  ...
</Settings>
"@

$TaskSequences = [pscustomobject]@TaskSequenceNumber=0;TaskSequenceName="01_Base",[pscustomobject]@TaskSequenceNumber=1;TaskSequenceName="02_XA"

#$xml = [xml](Get-Content -Path InputFile.xml)
#$TaskSequences = Get-RealDataFromSomeWhere

#Create new xml and remove root node
$newxml = [xml]@"
$($xml.FirstChild | ?  $_.NodeType -eq 'XmlDeclaration'  | %  $_.OuterXml )
<DeploymentScript>
  $($xml.SelectSingleNode("/Settings").OuterXml)
  <Deploy>
    $($TaskSequences | % 
    "<SequenceData>
        <TaskSequenceNumber>$($_.TaskSequenceNumber + 1)</TaskSequenceNumber>
        <TaskSequenceName>$($_.TaskSequenceName)</TaskSequenceName>
    </SequenceData>" )
  </Deploy>
</DeploymentScript>
"@


$newxml.Save("$env:USERPROFILE\Desktop\Test.xml")

Test.xml:

<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
  <Settings>
  ...
</Settings>
  <Deploy>
    <SequenceData>
      <TaskSequenceNumber>1</TaskSequenceNumber>
      <TaskSequenceName>01_Base</TaskSequenceName>
    </SequenceData>
    <SequenceData>
      <TaskSequenceNumber>2</TaskSequenceNumber>
      <TaskSequenceName>02_XA</TaskSequenceName>
    </SequenceData>
  </Deploy>
</DeploymentScript>

【讨论】:

非常感谢您的努力。根据您的代码,我得到了第一个结果。我已经用最新的代码编辑了我的请求。对于 "$SeqDataNode = ([xml]@" ..." 部分 -> 我仍然想知道,为什么你在那里编写纯 XML 代码?难道没有像“appendchild”这样的方法吗?你做到了吗?节省时间还是最好的方法? 我觉得所有的方法都很丑。对于这个简单的节点,我喜欢 xml 代码,但它可以很容易地重写为使用方法。和其他节点一样。 刚刚在我的主脚本中用扩展数据实现了这个。我认为这很好用。谢谢

以上是关于建立自定义 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

生成XML文件的

生成XML文件的

自定义控件的属性定义和使用

继承ViewGroup自定义View:步骤attrs.xmlTypedArray

在tomcat下建立自定义目录的应用

matlab怎么建立自定义函数