Powershell空XML元素格式为一行

Powershell空XML元素格式为一行,xml,powershell,Xml,Powershell,我需要我的XML格式与Powershell默认保存格式略有不同。下面是一个代码示例: [xml]$XML = New-Object system.Xml.XmlDocument $Declaration = $XML.CreateXmlDeclaration("1.0","UTF-8",$null) $XML.AppendChild($Declaration) > $null $Temp = $XML.CreateElement('Basket') $Temp.InnerText = $

我需要我的XML格式与Powershell默认保存格式略有不同。下面是一个代码示例:

[xml]$XML = New-Object system.Xml.XmlDocument
$Declaration = $XML.CreateXmlDeclaration("1.0","UTF-8",$null)
$XML.AppendChild($Declaration) > $null

$Temp = $XML.CreateElement('Basket')
$Temp.InnerText = $test
$XML.AppendChild($Temp)

$Temp1 = $XML.CreateElement('Item')
$Temp1.InnerText = ''
$Temp.AppendChild($Temp1)

$XML.save('test.xml')
这导致:

<?xml version="1.0" encoding="UTF-8"?>
<Basket>
  <Item>
  </Item>
</Basket>

我所需的XML应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Basket>
  <Item></Item>
</Basket>

这可能吗

如果我添加
XML.PreserveWhitespace=$true
所有内容都将在一行中结束。并且元素没有
PreserveWhitespace
属性

我找到的一个解决方案是添加一个空格
$Temp1.InnerText='
,然后在第二步中清理代码。但我想知道是否有一个技巧可以让Powershell在一行上输出空元素。 不幸的是,需要读取XML的目标应用程序只接受上述所需的格式

$Temp1.InnerText = ''
是您试图强制XML序列化使用单行
表单而不是自动关闭的
表单,因为-即使这两种表单应该是等效的,序列化XML的特定使用者(Adobe)也只接受
表单

您的尝试基于区分真正的空元素(没有子节点的元素)和具有空字符串文本子节点的元素(由
隐式创建。InnerText='
),希望具有子节点的元素(即使唯一的子节点是空字符串)始终以
形式序列化

您的尝试:

  • 不受类型的
    .Save()
    方法(提示您的问题)的尊重

    • 您遇到的特定行为最终被设计归类为-请参阅
  • 受到基于LINQ的类型的
    .Save()
    方法的嘉奖

因此,您有两种选择:


解决方法,如果您获得了一个现有的
XmlDocument
实例: 如果从
XmlDocument
实例的
.OuterXml
属性(
$XML.OuterXml
)返回的(非漂亮打印的)XML字符串构造
XDocument
实例,则使用所需的
表单将生成的
XDocument
实例保存到文件中,假设您在代码中保留了显式添加的空字符串子文本节点,即,
$Temp1.InnerText='


我仍然需要探索
XDocument
选项。他们现在给了我一个错误。但是,脚本太大、太复杂,此时无法重写。现在,在保存之前,我将使用
.Replace()
。感谢您的跟进;理解重写;不过,作为字符串替换的一种稍微简单的替代方法,答案中的变通方法可能仍然适用于您。
# Creates a pretty-printed XML file with the empty elements
# represented in "<tag></tag>" form from the System.Xml.XmlDocument
# instance stored in `$XML`.
([System.Xml.Linq.XDocument] $XML.OuterXml).Save("$PWD/test.xml")
# PSv5+ syntax for simplifying type references.
using namespace System.Xml.Linq

# Create the XDocument with its  declaration.
$xd = [XDocument]::new(
        # Note: [NullString]::Value is needed to pass a true null value - $null doesn't wor.
        [XDeclaration]::new('1.0', 'UTF-8', [NullString]::Value)
      )

# Add nodes.
$xd.Add(($basket = [XElement] [XName] 'Basket'))
$basket.Add(($item = [XElement] [XName] 'Item'))

# Add an empty-string child node to the '<Item>' element to
# force it to serialize as '<Item></Item>' rather than as '<Item />'
$item.SetValue('')

# Save the document to a file.
$xd.Save("$PWD/test.xml")