开发者

Can I add the xml-transform processing instruction to the xml returned from a wcf service contract

I have a restful wcf service that returns xml. I had the idea to add an xsl-transform processing instruction to the xml in order to beutify the data when viewed through a web browser.

Mission objective #1: add <?xml-stylesheet type="text/xsl" href="style.xsl"?> to returned xml

I tried out the following method; http://shevaspace.blogspot.com/2009/01/include-xml-declaration-in-wcf-restful.html The recommended way to add the xml-s开发者_开发技巧tylesheet tag to xml documents seem to be the WriteProcessingInstruction method, but System.Xml.XmlDictionaryWriter doesn't allow any calls to WriteProcessingInstruction( string name, string text ) with the name parameter being anythin other than "xml". WriteRaw isn't allowed either, since it can only write data within the xml root node.

Is there a way to attach the xml-stylesheet tag to the returned xml from a wcf service?


I accomplished this by implementing my own XmlWriter that writes out the processing instruction. (In my case, only for responses in selected namespaces):

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;
    }
}

Of course, in typical WCF fashion the hardest part of the exercise is to get WCF to use this. For me, this involved:

  • Implementing a custom WebServiceHost and WebServiceHostFactory
  • Replacing the WebMessageEncodingBindingElement of the ServiceEndpoints with a custom MessageEncodingBindingElement
  • Overriding MessageEncodingBindingElement.CreateMessageEncoderFactory to return a custom MessageEncoderFactory
  • Implementing a custom MessageEncoderFactory that returns a custom MessageEncoder on the Encoder property
  • Implementing a custom MessageEncoder that uses the StylesheetXmlTextWriter in its WriteMessage implementations
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜