Можно ли добавить инструкцию обработки xml-transform в xml, возвращаемый из контракта на обслуживание wcf - PullRequest
1 голос
/ 21 января 2011

У меня есть спокойный сервис wcf, который возвращает xml.У меня была идея добавить инструкцию обработки xsl-transform в xml, чтобы улучшить данные при просмотре через веб-браузер.

Цель миссии № 1: add <?xml-stylesheet type="text/xsl" href="style.xsl"?> to returned xml

Я опробовал следующий метод;http://shevaspace.blogspot.com/2009/01/include-xml-declaration-in-wcf-restful.html Рекомендованным способом добавления тега xml-stylesheet в документы xml является метод WriteProcessingInstruction, но System.Xml.XmlDictionaryWriter не допускает никаких вызовов к WriteProcessingInstruction( string name, string text ) с параметром name, отличным от любого, кроме"XML".WriteRaw также не допускается, поскольку он может записывать данные только в корневой узел xml.

Есть ли способ присоединить тег xml-stylesheet к возвращенному XML из службы wcf?

1 Ответ

2 голосов
/ 25 февраля 2011

Я достиг этого, реализовав свой собственный XmlWriter, который выписывает инструкцию обработки. (В моем случае только для ответов в выбранных пространствах имен):

public class StylesheetXmlTextWriter : XmlTextWriter
{
    private readonly string _filename;
    private readonly string[] _namespaces;
    private bool firstElement = true;

    public StylesheetXmlTextWriter(Stream stream, Encoding encoding, string filename, params string[] namespaces) : base(stream, encoding)
    {
        _filename = filename;
        _namespaces = namespaces;
    }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        if (firstElement && (_namespaces.Length == 0 || _namespaces.Contains(ns)))
            WriteProcessingInstruction("xml-stylesheet", string.Format("type=\"text/xsl\" href=\"{0}\"", _filename));

        base.WriteStartElement(prefix, localName, ns);
        firstElement = false;
    }
}

Конечно, в типичной моде WCF самая сложная часть упражнения - заставить WCF использовать это. Для меня это связано:

  • Реализация пользовательского WebServiceHost и WebServiceHostFactory
  • Замена элемента WebMessageEncodingBinding элемента ServiceEndpoints пользовательским элементом MessageEncodingBindingElement
  • Переопределение MessageEncodingBindingElement.CreateMessageEncoderFactory для возврата пользовательского MessageEncoderFactory
  • Реализация пользовательского MessageEncoderFactory, который возвращает пользовательский MessageEncoder в свойстве Encoder
  • Реализация пользовательского MessageEncoder, который использует StylesheetXmlTextWriter в своих реализациях WriteMessage
...