我可以将xml-transform处理指令添加到从wcf服务契约返回的xml中

时间:2011-01-21 13:43:09

标签: xml wcf stylesheet

我有一个返回xml的restful wcf服务。我有想法在xml中添加xsl-transform处理指令,以便在通过Web浏览器查看数据时获得数据。

任务目标#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参数为anythin除了“XML”。也不允许WriteRaw,因为它只能在xml根节点中写入数据。

有没有办法将xml-stylesheet标记附加到wcf服务返回的xml?

1 个答案:

答案 0 :(得分:2)

我通过实现自己编写处理指令的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
  • 使用自定义MessageEncodingBindingElement替换ServiceEndpoints的WebMessageEncodingBindingElement
  • 重写MessageEncodingBindingElement.CreateMessageEncoderFactory以返回自定义MessageEncoderFactory
  • 实现在Encoder属性上返回自定义MessageEncoder的自定义MessageEncoderFactory
  • 实现在其WriteMessage实现中使用StylesheetXmlTextWriter的自定义MessageEncoder