$Temp1.InnerText = ''
- это ваша попытка заставить сериализацию XML использовать однострочную <tag></tag>
форму, а не самозакрывающуюся <tag />
форму , потому что - хотя обе формы если эквивалентно, то конкретный потребитель вашего сериализованного XML (Adobe) принимает только форму <tag></tag>
.
Ваша попытка основана на различении действительно пустого элемента - одинкоторый не имеет дочерних узлов - и тот, который имеет пустую строку текст дочерний узел (неявно созданный .InnerText = ''
), в надежде, что элемент с дочерними узлами - хотя единственным дочерним узлом является пустая строка - всегда сериализуется в форме <tag>...</tag>
.
Ваша попытка:
не соблюдается с помощью XmlDocument
типа .Save()
(который вызвал ваш вопрос)
- Специфическое поведение, с которым вы столкнулись, должно рассматриваться как ошибка [1] (начиная с .NETCore 3.0) и сообщалось в об этой проблеме GitHub .
соблюдается LINQ* на основе XDocument
тип, .Save()
метод.
Таким образом, у вас есть два варианта:
Обходной путь, если вам дан существующий экземпляр XmlDocument
:
Если вы создаете экземпляр XDocument
из (не очень напечатанной) XML-строки, возвращаемой .OuterXml
вашего экземпляра XmlDocument
* свойство ($XML.OuterXml
), при сохранении полученного экземпляра XDocument
в файл используется требуемая форма <tag></tag>
, при условии, что вы сохранили явно добавленный дочерний текстовый узел с пустой строкой в своем коде , т. е. $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
, как показано ниже.
AlВ итоге, вы можете создать свой 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")
[1] Пробел внутри и элемент имеет значение и считается частью внутреннего текста (значение дочернего текстового узла), поэтому двухстрочное представлениеItem
элементы не эквивалентны <Item></Item>