Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的内联CSS#_C#_Css_Inlining - Fatal编程技术网

C# C语言中的内联CSS#

C# C语言中的内联CSS#,c#,css,inlining,C#,Css,Inlining,我需要从c#中的样式表内联css 就像这样 css很简单,只是类,没有花哨的选择器 我曾考虑使用正则表达式(?(?[^{}]+){(?[^{}]+})+从css中去除规则,然后尝试在调用类的地方进行简单的字符串替换,但一些html元素已经有一个样式标记,因此我也必须考虑这一点 有没有更简单的方法?还是已经用c#写的东西 更新-2010年9月16日 我已经能够提出一个简单的CSS内联,只要您的html也是有效的xml。它使用正则表达式获取元素中的所有样式。然后将css选择器转换为xpath表达式

我需要从c#中的样式表内联css

就像这样

css很简单,只是类,没有花哨的选择器

我曾考虑使用正则表达式
(?(?[^{}]+){(?[^{}]+})+
从css中去除规则,然后尝试在调用类的地方进行简单的字符串替换,但一些html元素已经有一个样式标记,因此我也必须考虑这一点

有没有更简单的方法?还是已经用c#写的东西

更新-2010年9月16日 我已经能够提出一个简单的CSS内联,只要您的html也是有效的xml。它使用正则表达式获取
元素中的所有样式。然后将css选择器转换为xpath表达式,并在任何预先存在的内联样式之前,将内联样式添加到匹配元素中

注意,CssToXpath没有完全实现,有些事情它就是做不到。。。然而

CssInliner.cs

using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Xml.XPath;

namespace CssInliner
{
    public class CssInliner
    {
        private static Regex _matchStyles = new Regex("\\s*(?<rule>(?<selector>[^{}]+){(?<style>[^{}]+)})",
                                                RegexOptions.IgnoreCase
                                                | RegexOptions.CultureInvariant
                                                | RegexOptions.IgnorePatternWhitespace
                                                | RegexOptions.Compiled
                                            );

        public List<Match> Styles { get; private set; }
        public string InlinedXhtml { get; private set; }

        private XElement XhtmlDocument { get; set; }

        public CssInliner(string xhtml)
        {
            XhtmlDocument = ParseXhtml(xhtml);
            Styles = GetStyleMatches();

            foreach (var style in Styles)
            {
                if (!style.Success)
                    return;

                var cssSelector = style.Groups["selector"].Value.Trim();
                var xpathSelector = CssToXpath.Transform(cssSelector);
                var cssStyle = style.Groups["style"].Value.Trim();

                foreach (var element in XhtmlDocument.XPathSelectElements(xpathSelector))
                {
                    var inlineStyle = element.Attribute("style");

                    var newInlineStyle = cssStyle + ";";
                    if (inlineStyle != null && !string.IsNullOrEmpty(inlineStyle.Value))
                    {
                        newInlineStyle += inlineStyle.Value;
                    }

                    element.SetAttributeValue("style", newInlineStyle.Trim().NormalizeCharacter(';').NormalizeSpace());
                }
            }

            XhtmlDocument.Descendants("style").Remove();
            InlinedXhtml = XhtmlDocument.ToString();
        }

        private List<Match> GetStyleMatches()
        {
            var styles = new List<Match>();

            var styleElements = XhtmlDocument.Descendants("style");
            foreach (var styleElement in styleElements)
            {
                var matches = _matchStyles.Matches(styleElement.Value);

                foreach (Match match in matches)
                {
                    styles.Add(match);
                }
            }

            return styles;
        }

        private static XElement ParseXhtml(string xhtml)
        {
            return XElement.Parse(xhtml);
        }
    }
}
还有一些测试

    [TestMethod]
    public void TestCssToXpathRules()
    {
        var translations = new Dictionary<string, string>
                               {
                                   { "*", "//*" }, 
                                   { "p", "//p" }, 
                                   { "p > *", "//p/*" }, 
                                   { "#foo", "//*[@id='foo']" }, 
                                   { "*[title]", "//*[@title]" }, 
                                   { ".bar", "//*[contains(concat(' ',normalize-space(@class),' '),' bar ')]" }, 
                                   { "div#test .note span:first-child", "//div[@id='test']//*[contains(concat(' ',normalize-space(@class),' '),' note ')]//*[1]/self::span" }
                               };

        foreach (var translation in translations)
        {
            var expected = translation.Value;
            var result = CssInliner.CssToXpath.Transform(translation.Key);

            Assert.AreEqual(expected, result);
        }
    }

    [TestMethod]
    public void HtmlWithMultiLineClassStyleReturnsInline()
    {
        #region var html = ...
        var html = XElement.Parse(@"<html>
                                        <head>
                                            <title>Hello, World Page!</title>
                                            <style>
                                                .redClass { 
                                                    background: red; 
                                                    color: purple; 
                                                }
                                            </style>
                                        </head>
                                        <body>
                                            <div class=""redClass"">Hello, World!</div>
                                        </body>
                                    </html>").ToString();
        #endregion

        #region const string expected ...
        var expected = XElement.Parse(@"<html>
                                            <head>
                                                <title>Hello, World Page!</title>
                                            </head>
                                            <body>
                                                <div class=""redClass"" style=""background: red; color: purple;"">Hello, World!</div>
                                            </body>
                                        </html>").ToString();
        #endregion

        var result = new CssInliner.CssInliner(html);

        Assert.AreEqual(expected, result.InlinedXhtml);
    }
好问题

我不知道是否有.NET解决方案,但我发现了一个名为的Ruby程序,它声称可以内联CSS。如果你想使用它,你有几个选择:

  • 用C#(或您熟悉的任何.NET语言)重写预编译器
  • 用于在.NET中运行Ruby

  • 这里有一个想法,你为什么不打个电话来使用c。从使用firebug的分析来看,post调用似乎需要两个参数htmlstrip,它们取值(开/关),结果是一个名为text的参数


    下面是一个关于如何创建一个

    Chad的示例,您是否必须添加CSS内联?或者在
    中添加一个
    块会更好吗?这将在本质上取代对CSS文件引用的需要,并维护实际内联规则覆盖头/引用CSS文件中设置的规则


    (对不起,忘记添加代码的引号了)

    我推荐这样的口述:

    private Dictionary<string, Dictionary<string, string>> cssDictionary = new Dictionary<string, Dictionary<string, string>();
    

    private Dictionary cssDictionary=new Dictionary既然您的当前实现已经完成了90%的工作,为什么不使用现有的框架,而用HTML解析器代替XML解析呢?其中一个更受欢迎的是。它支持XPath查询,甚至有一个类似于为XML提供的标准.NET接口的LINQ接口,因此它应该是一个相当简单的替代品。

    我建议使用实际的CSS解析器,而不是正则表达式。您不需要解析完整的语言,因为您主要对复制感兴趣,但在任何情况下都可以使用这样的解析器(对于.NET也是如此)。例如,看看antlr,特别是a或a语法。如果您不介意次优结果(其中内联样式可能包含重复的定义),那么您可能会剥离这两个语法的大部分,但要做到这一点,您需要了解一些内部CSS逻辑,以便能够解析速记属性


    但是,从长远来看,这肯定比一系列临时正则表达式修复要少得多。

    我在Github上有一个项目,它使CSS内联。它非常简单,并且支持移动风格。请在我的博客上阅读更多内容:

    因为这个选项在其他回复中不是很清楚,我认为它应该得到一个直截了当的回答

    使用

    你所要做的就是:

  • 通过nuget安装PreMailer.NET
  • 键入以下内容:

    var inlineStyles = PreMailer.Net.PreMailer.MoveCssInline(htmlSource, false);
    destination = inlineStyles.Html;
    
  • 你完了

    顺便说一句,您可能需要使用
    指令添加一个
    ,以缩短该行


    当然,在上面的链接中有更多的使用信息。

    添加了一个悬赏,希望有人已经有东西在里面了。NETI希望你得到一些信息,我不喜欢我的答案。@Greg,这里也是!我正在尝试写一些简单的东西…它不会这么简单…添加了我用于解决方案的代码。请随意改进它。CssToXpath类肯定还可以使用一些增强功能,但它目前符合我的目的。嘿-我刚刚在博客中介绍了我的解决方案,PreMailer.Net:是的,css已经在
    元素中,但是BB电子邮件客户端似乎不支持它。但是它确实支持内联样式。CSS内联用于HTML电子邮件有多种原因。主要原因是,许多web电子邮件客户端在将现有样式块包含到自己的html输出之前,会将其从html电子邮件源中剥离出来。但还有Outlook,即使在2019年,它也是一个糟糕的HTML电子邮件客户端,如果不内联CSS样式,你将永远无法驯服它。依赖另一个网站在线、快速且不改变,这个应用程序至关重要。我实际上写了一些类似的东西,效果相当不错。它远非完美无缺,但运行得相当好。我会尝试将其打包并发布到这里。如果我在当前的实现中遇到任何问题,我会对此进行调查。现在,我知道我的“html”是有效的xml,所以xml解析很好,它正在生产中工作。此外,html Agility Pack的解析器甚至不能很好地处理有效的html,例如
    • x
    • y
    • z
    ——它的健壮性不足以处理现实世界的html。请查看此线程()用于讨论其他HTML解析器以及HTML敏捷包。如果它成为一个问题,我可能会这样做。很好。似乎大部分都能工作,但当我使用Zurb“Ink basic template”尝试它时,我得到以下警告:“由于CsQuery中的限制,PreMailer.Net无法处理伪类/元素“a:active”。-我想这取决于CsQuery来解决。顺便说一句,这篇文章说CsQuery现在确实支持它们@MatthewLock是的,正如你链接到的GitHub问题中所描述的,现在有一个问题。亲爱的@MartinHN感谢kind项目,我在使用MoveCssInline时遇到了一个问题,我得到了这个异常(在位置34处发现了意外字符:“…rol solid::>>-@Younisbarznji你能粘贴y吗
    
    private Dictionary<string, Dictionary<string, string>> cssDictionary = new Dictionary<string, Dictionary<string, string>();
    
    Dictionary<string,string> bodyStyleDictionary = new Dictionary<string, string();
        bodyStyleDictionary.Add("background", "#000000");
        cssDictionary.Add("body", bodyStyleDictionary);
    
    var inlineStyles = PreMailer.Net.PreMailer.MoveCssInline(htmlSource, false);
    destination = inlineStyles.Html;