Как записать логический атрибут (указанный - не указанный) с помощью XmlWriter?

Есть ли способ написать атрибут без значения:

<element specified/>

Я считаю, что могу сделать это с помощью:

writer.WriteRaw("<element specified/>")

Но есть ли способ сделать это с помощью WriteAttributeString, WriteStartAttribute, WriteAttributes или других методов?


person Vitaliy    schedule 14.11.2011    source источник
comment
возможный дубликат является допустимым атрибутом xml без значения?   -  person Damith    schedule 14.11.2011
comment
<element specified/> не является правильно сформированным XML и не может быть проанализирован никаким программным обеспечением XML, все они вызовут ошибку. Однако это действующий SGML (а иногда и действующий HTML). Использование WriteRaw — единственный способ обойти правила и написать незаконный XML.   -  person Abel    schedule 14.11.2011
comment
@UnhandledException - повторяющийся вопрос не связан с вопросом, который я написал - как создать логический атрибут с помощью XmlWriter   -  person Vitaliy    schedule 14.11.2011


Ответы (1)


Если вам нужно написать структуру SGML в старом стиле, вы можете рассмотреть возможность использования HtmlTextWriter или любой из его потомков, например XhtmlTextWriter. Их первоначальные намерения заключались в использовании в ASP.NET, но, поскольку они являются производными от TextWriter, их можно использовать и в других сценариях.

Если вам нужна еще большая гибкость, было бы неплохо иметь SGMLWriter. К сожалению, мне удалось найти только SGMLReader.

Редактировать

Вы можете создать XmlWriter, который записывает допустимый HTML, который не является допустимым XML, как в HTML 3.2 или 4.0. Вы можете сделать это, перезаписав OutputMethod с помощью отражения (это свойство доступно только для чтения, иначе оно не позволит вам сделать это, насколько я понял). Пример:

XmlWriterSettings settings = new XmlWriterSettings();

// Use reflection, not that you need GetMethod, not GetProperty
MethodInfo propOutputMethod = settings.GetType().GetMethod("set_OutputMethod", 
    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod);
propOutputMethod.Invoke(settings, new object[] { XmlOutputMethod.Html });

// check value, it should contain XmlOutputMethod.Html now
var outputMethod = settings.OutputMethod;

// continue as you used to do
StringBuilder builder = new StringBuilder();
XmlWriter writer = XmlWriter.Create(builder, settings);
writer.WriteStartDocument();
writer.WriteStartElement("html");
writer.WriteStartElement("input");
writer.WriteAttributeString("ismap", "value");
writer.WriteEndElement();
writer.WriteElementString("br", null);
writer.WriteElementString("img", null);
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();

// variable output will now contain "<html><input ismap><br><img></html>"
string output = builder.ToString();

Важное примечание: это будет работать только для предопределенных атрибутов и тегов. Насколько мне известно, это можно сделать только с теми, которые определены в спецификации HTML 4.0 как логические или как теги, не требующие закрытия (br, img, hr и т. д.).

Кроме того, если вы попытаетесь создать недопустимые комбинации, будет использоваться стандартный синтаксис. Невозможно принудительно задать логический атрибут без ="". То есть это работает: <input ismap>, это не работает <inputs ismap=""></inputs>.

person Abel    schedule 14.11.2011
comment
вероятно, вы правы, и мне нужно использовать что-то вроде HtmlTextWriter. Мне было интересно, что свойство XmlWriterSettings.OutputMethod только для чтения принимает Xml, Text, Html. Так что, вероятно, XmlWriter также позволяет писать неправильный HTML? - person Vitaliy; 14.11.2011
comment
@Vitaly: я проверил установку OutputMethod на другое значение. Он пишет HTML, но пока он также является действительным XHTML, и я не смог заставить его записывать пустые необязательные атрибуты. Однако, если вы посмотрите документацию, вы увидите, что этот параметр используется только внутри XsltProcessor .NET. Внутри он использует HtmlUtf8RawTextWriter (скрытый класс). - person Abel; 14.11.2011
comment
спасибо за пример - это именно то, что я искал - person Vitaliy; 17.11.2011