首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >是否可以将XSLT样式表添加到序列化的XML文档?

是否可以将XSLT样式表添加到序列化的XML文档?
EN

Stack Overflow用户
提问于 2009-09-22 16:08:01
回答 4查看 6.2K关注 0票数 19

我有将复杂对象序列化为XML并将其另存为文件的代码,有没有在序列化期间在xml中包含样式表的快速方法?

使用C#和.net框架v2。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-22 16:23:49

您可以使用XmlWriterWriteProcessingInstruction

代码语言:javascript
复制
    XmlSerializer s = new XmlSerializer(typeof(myObj));
    using (XmlWriter w = XmlWriter.Create(@"c:\test.xml"))
    {
        w.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"USED-FILE.xsl\"");
        s.Serialize(w, myObj);
    }
票数 32
EN

Stack Overflow用户

发布于 2018-11-03 17:24:05

对于那些想知道如何在现代dotnet核心中实现类似功能的人来说,你需要做一些调整:

代码语言:javascript
复制
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection;

namespace ContentNegotiation
{
    public class Program
    {
        public static void Main(string[] args) => CreateWebHostBuilder(args).Build().Run();

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }

    public class MyXmlSerializerOutputFormatter : XmlSerializerOutputFormatter
    {
        protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
        {
            // TODO: add me only if controller has some kind of custom attribute with XSLT file name
            xmlWriter.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"template.xsl\"");
            base.Serialize(xmlSerializer, xmlWriter, value);
        }
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options =>
            {
                options.RespectBrowserAcceptHeader = true; // default is false
                // options.OutputFormatters.Add(new XmlSerializerOutputFormatter()); // not enough
                options.OutputFormatters.Add(new MyXmlSerializerOutputFormatter());
            })
            // .AddXmlSerializerFormatters() // does not added by default, but not enough
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseStaticFiles();
            app.UseMvc();
        }
    }

    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Body { get; set; }
    }

    [ApiController]
    public class DemoController : ControllerBase
    {
        // curl -k -i -s -H 'Accept: text/xml' http://localhost:5000/posts
        // curl -k -i -s -H 'Accept: application/json' http://localhost:5000/posts
        [HttpGet]
        [Route(nameof(Posts))]
        public IEnumerable<Post> Posts() => new[] {
            new Post {
                Id = 1,
                Title = "Hello World",
                Body = "Lorem ipsum dot color"
            },
            new Post {
                Id = 2,
                Title = "Post 2",
                Body = "Lorem ipsum dot color"
            }
        };
    }
}

我们在ConfigureServices中开启了内容协商,并给出了我们的XmlSerializerOutputFormatter实现,它将把XSL添加到输出中。

因此,现在我们的后端将使用JSON响应如下请求:

代码语言:javascript
复制
curl -k -i -s -H 'Accept: application/json' http://localhost:5000/posts

和XML:

代码语言:javascript
复制
curl -k -i -s -H 'Accept: text/xml' http://localhost:5000/posts

用于演示目的的xsl示例可以在以下位置找到:https://mac-blog.org.ua/dotnet-content-negotiation/

票数 1
EN

Stack Overflow用户

发布于 2018-09-13 04:23:55

我写这篇文章是为了将问题简化为只在类上添加一个属性,就像我们描述其他所有xml构造指令一样:

用法为:

代码语言:javascript
复制
    [XmlStylesheet("USED-FILE.xsl")]
    public class Xxx
    {
        // etc
    }


    Xxx x = new Xxx();

    XmlSerializer s = new XmlSerializer(typeof(Xxx));
    using (var  tw = File.CreateText(@"c:\Temp\test.xml"))
    using (var xw = XmlWriter.Create(tw))
    {
        s.SerializeWithStyle(xw, x);    // only line here that needs to change. 
                                        // rest is standard biolerplate.
    }

所需的库代码:(保持在相同的名称空间中,因此当IntelliSense为属性添加名称空间时,它也会拉入扩展方法)

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using System.Reflection;
using System.Xml;

namespace NovelTheory.Xml.Serialization
{
    public class XmlStylesheetAttribute : Attribute
    {
        public string Href { get; set; }
        public XmlStylesheetAttribute(string href)
        {
            Href = href;
        }
    }

    public static class XmlStylesheetAttributeExtenstions
    {
        public static void SerializeWithStyle(this XmlSerializer serializer, 
                XmlWriter textWriter, object o)
        {
            AddStyleSheet(textWriter, o);
            serializer.Serialize(textWriter, o);
        }

        public static void SerializeWithStyle(this XmlSerializer serializer, 
                XmlWriter textWriter, object o, XmlSerializerNamespaces namespaces)
        {
            AddStyleSheet(textWriter, o);
            serializer.Serialize(textWriter, o, namespaces);
        }
        private static void AddStyleSheet(XmlWriter textWriter, object o)
        {
            var dnAttribute = o.GetType()
                                            .GetTypeInfo()
                                            .GetCustomAttribute<XmlStylesheetAttribute>();
            if (dnAttribute != null)
                textWriter.WriteProcessingInstruction("xml-stylesheet", 
                                        $@"type=""text/xsl"" href=""{dnAttribute.Href}""");
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1461029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档