【问题标题】:Powershell empty XML element formatted to be one line格式化为一行的 Powershell 空 XML 元素
【发布时间】:2020-02-05 06:51:17
【问题描述】:

我需要我的 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 的目标应用程序将只接受上述要求的格式。

【问题讨论】:

  • 我仍然需要探索XDocument 选项。他们目前给我一个错误。但是,此时脚本太大且太复杂,无法重写。现在我将在保存之前使用.Replace()
  • 感谢您的关注;理解重写;不过,答案中的 workaround 可能仍然对您有用,作为字符串替换的稍微简单的替代方法。

标签: xml powershell


【解决方案1】:
$Temp1.InnerText = ''

您试图强制 XML 序列化使用单行 &lt;tag&gt;&lt;/tag&gt; 表单而不是自动关闭 &lt;tag /&gt; 表单,因为 - 即使这两种表单都应该 等价,您的序列化 XML (Adobe) 的特定使用者仅接受 &lt;tag&gt;&lt;/tag&gt; 表单。

您的尝试基于区分 真正的空 元素 - 一个没有子节点的元素 - 和一个具有 empty-string 文本 子节点的元素(由.InnerText = '' 隐式创建),希望元素带有子节点——即使唯一的子节点是空字符串——总是序列化在&lt;tag&gt;...&lt;/tag&gt; 表单中。

你的尝试:

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

  • 受基于 LINQ 的 XDocument 类型的 .Save() 方法认可。

    李>

因此,您有两种选择:


解决方法,如果您有一个现有的 XmlDocument 实例:

如果您从XmlDocument 实例的.OuterXml 属性($XML.OuterXml) 返回的(非漂亮打印的)XML 字符串构造XDocument 实例,则将生成的XDocument 实例保存到文件中使用所需的&lt;tag&gt;&lt;/tag&gt; 表单,假设您在代码中保留了显式添加的空字符串子文本节点,即$Temp1.InnerText = ''

# 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")

虽然这涉及到一轮额外的序列化和解析,但它是一种简单实用的解决方案。

如果 XML DOM 对象没有提供给您并且您可以选择自己构建它,那么最好先将其构建为 XDocument 实例,如下所示。


或者,您可以将您的 XML 文档直接构造为XmlDocument

首先将您的文档构造为XDocument 实例:

# 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")

【讨论】:

    猜你喜欢
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 2021-09-09
    • 2017-01-26
    相关资源
    最近更新 更多