Я получаю XML следующим образом:
<Items>
<Row attr1="val"></Row>
<Row attr1="val2"></Row>
</Items>
Это правильный XML, как вы знаете, но другая библиотека, которую я использую, отключена, и она будет принимать XML только в этом формате:
<Items>
<Row attr1="val"/>
<Row attr1="val2"/>
</Items>
Я уже читаю XML в XmlDocuments, манипулируя ими и переписывая их с помощью XmlWriter(), что самый простой (и самый эффективный) способ "свернуть" эти пустые теги?
Задайте свойство IsEmpty каждого XmlElement, который вы хотите свернуть до истины.
Здесь рекурсивный метод:
private static void FormatEmptyNodes(XmlNode rootNode)
{
foreach (XmlNode childNode in rootNode.ChildNodes)
{
FormatEmptyNodes(childNode);
if(childNode is XmlElement)
{
XmlElement element = (XmlElement) childNode;
if (string.IsNullOrEmpty(element.InnerText)) element.IsEmpty = true;
}
}
}
Используется следующим образом:
var doc = new XmlDocument();
doc.Load(inputFilePath);
FormatEmptyNodes(doc);
doc.Save(outputFilePath);
Если вы уже используете XmlWriter для записи своего XML, он должен уже сбрасывать пустые элементы. Этот код (с использованием .Net 3.5):
XmlWriter xw = XmlWriter.Create(Console.Out);
xw.WriteStartElement("foo");
xw.WriteAttributeString("bar", null, "baz");
xw.WriteEndElement();
xw.Flush();
xw.Close();
испускает <foo bar='baz' />
.
Если ваш XmlWriter не указан, вы должны проверить, чтобы ваш код XmlWriter не выдавал текстовые узлы, которых вы не ожидаете.
Вы можете попробовать это.
Подкласс XmlTextWriter с реализацией, чей WriteFullEndElement вызывает base.WriteEndElement. Вот так:
public class BetterXmlTextWriter : XmlTextWriter
{
public BetterXmlTextWriter(TextWriter w)
: base(w)
{
}
public override void WriteFullEndElement()
{
base.WriteEndElement();
}
}
Затем напишите документ в экземпляр вашего подкласса, используя XmlDocument.WriteContentTo.
Если вы используете объекты манипуляции с объектами System.XML DOM (XmlElement и т.д.) вместо XmlWriter, вы получите это бесплатно.
XmlElement items = xmlDoc.SelectNodes("items");
XmlElement row = xmlDoc.CreateElement("row");
items[0].appendChild(row);
Вы получите "< row/ > "