Можем ли мы заставить XmlWriter выдавать ‹my-tag›‹/my-tag› вместо ‹my-tag/›?

По умолчанию,

someXmlWriter.WriteElementString("my-tag", someString);

производит <my-tag />

Я просмотрел XmlWriterSettings. class для возможных вариантов, которые заставили бы автора создавать вместо этого <my-tag></my-tag>, но ничего не нашел.

Есть ли простой способ заставить XmlWriter для выдачи пустых элементов с «открытым тегом, закрытым тегом», а не с сокращенной формой?

Изменить:
Да! Я понимаю, что в отношении достоверности XML две нотации эквивалентны, действительны и все такое... Однако я работаю с устаревшим кодом, который анализирует такой XML с помощью Read(), т.е. на уровне узла (!) и возится с помощью Read ()-ing на пустом узле...

Следовательно, мой вопрос возникает в контексте ограничения количества изменений в этом устаревшем коде. Вопрос действительно перекрывается с этим вопросом SO, как было предложено; ни один из предложенных там вариантов, однако, не может быть легко применим к моей ситуации.


person mjv    schedule 25.01.2012    source источник
comment
возможный дубликат C#: XmlTextWriter.WriteElementString не работает с пустыми строками?   -  person nemesv    schedule 26.01.2012
comment
Вы можете найти решение здесь: stackoverflow.com/questions/13389960/ Это работает для меня.   -  person Portekoi    schedule 07.06.2013


Ответы (7)


Это сработало для меня:

writer.WriteStartElement("my-tag");
writer.WriteRaw(someString);
writer.WriteFullEndElement();

WriteEndElement по-прежнему самостоятельно закрывает тег

person mejobloggs    schedule 11.07.2012
comment
в моих тестах, если я делаю write.WriteRaw(), а затем Writer.WriteEndElement(), мои теги не закрываются сами по себе. ВС 2010. - person CD Jorgensen; 28.02.2013

Если вы получили сообщение Extension method can only be declared in non-generic, non-nested static class, поскольку слово this может быть выделено, просто создайте класс расширения, как показано ниже:

public static class Extension
{
    public static void WriteFullElementString(this XmlTextWriter writer, string localName, string value)
    {
        writer.WriteStartElement(localName);
        writer.WriteRaw(value);
        writer.WriteFullEndElement();
    }
}

Надеюсь, это окажется полезным :-)

person iggyweb    schedule 29.01.2015

Попробуй это:

x.WriteStartElement("my-tag"); 

//Value of your tag is null

If (<"my-tag"> == "")

{
  x.WriteWhitespace("");
}else
  x.WriteString(my-tag);

x.WriteEndElement();
person rafael.vidal    schedule 06.01.2016

Вы пробовали что-то вроде этого:

if (someString.Length > 0)
{
  someXmlWriter.WriteElementString("my-tag", someString);
}
else
{
  someXmlWriter.WriteStartElement("my-tag");
  someXmlWriter.WriteEndElement("my-tag");
}

Может быть, сделать служебный класс с этим в качестве функции-члена.

person DwB    schedule 25.01.2012
comment
Я не пробовал, но подозреваю, что это сработает. Увы, я работаю с устаревшим кодом и стремился к подходу с наименьшими изменениями... - person mjv; 26.01.2012
comment
служебный класс или производный класс XmlWriter, выполняющий указанные выше действия. И то, и другое, вероятно, потребует большого количества правок, но также может быть подход с наименьшими изменениями. - person DwB; 26.01.2012
comment
Действительно, это решение также предлагается в дублирующем вопросе, упомянутом выше, вместе с идеей сделать это методом расширения. Если ничего не получится, я могу просто сделать это или переписать синтаксический анализатор, чтобы он работал на уровне элемента. В любом случае, спасибо за предложение - person mjv; 26.01.2012

Оставьте это здесь на случай, если кому-то это понадобится; так как ни один из приведенных выше ответов не решил это для меня или не казался излишним.

    FileStream fs = new FileStream("file.xml", FileMode.Create);
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    XmlWriter w = XmlWriter.Create(fs, settings);
    w.WriteStartDocument();
    w.WriteStartElement("tag1");

        w.WriteStartElement("tag2");
        w.WriteAttributeString("attr1", "val1");
        w.WriteAttributeString("attr2", "val2");
        w.WriteFullEndElement();

    w.WriteEndElement();
    w.WriteEndDocument();
    w.Flush();
    fs.Close();

Хитрость заключалась в том, чтобы установить XmlWriterSettings.Indent = true и добавить его в XmlWriter.

Изменить:

В качестве альтернативы вы также можете использовать

w.Formatting = Formatting.Indented;

вместо добавления XmlWriterSettings.

person PhoenixDev    schedule 09.09.2015

Я использую следующий код:

if (string.IsNullOrEmpty(myStringValue))
{
   myWriter.WriteStartElement("mytag");
   myWriter.WriteFullEndElement();
}
else
{
   myWriter.WriteElementString("mytag", myStringValue);
}
person Juan Carlos Velez    schedule 15.04.2016

Я только что столкнулся с точно такой же проблемой, и, хотя это похоже на взлом, это действительно сработало и было очень ненавязчивым для существующего кода, с которым мне приходилось работать.

private static XElement MakeElementLongHand(this XElement rootElem)
{
   rootElem.Value = " ";
   rootElem.Value = string.Empty;
   return rootElem;
}
person Steve Danner    schedule 21.09.2012