【问题标题】:Looking for a CSS Parser in java [closed]在java中寻找CSS解析器[关闭]
【发布时间】:2009-10-03 12:12:04
【问题描述】:

我正在寻找 Java 中的 CSS 解析器。特别是我的要求是,对于 HTML 文档中的给定节点/元素,能够从解析器中询问/获取该元素的 css 样式。

我知道有 W3C SAC 接口和基于此的一两个实现 - 但教程/示例似乎不存在。

非常感谢任何正确方向的帮助/点。

谢谢

【问题讨论】:

标签: java css parsing


【解决方案1】:

我用过CSSParser,我喜欢它——它也能对错误提供很好的反馈。

这是我找到并修改的一些示例代码:

package com.dlogic;

import com.steadystate.css.parser.CSSOMParser;
import org.w3c.css.sac.InputSource;
import org.w3c.dom.css.CSSStyleSheet;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSRule;
import org.w3c.dom.css.CSSStyleRule;
import org.w3c.dom.css.CSSStyleDeclaration;
import java.io.*;


public class CSSParserTest 
{

    protected static CSSParserTest oParser;

    public static void main(String[] args) {

            oParser = new CSSParserTest();

            if (oParser.Parse("design.css")) {

                System.out.println("Parsing completed OK");

            } else {

                System.out.println("Unable to parse CSS");

            }   
    }


     public boolean Parse(String cssfile) 
     {

         FileOutputStream out = null; 
         PrintStream ps = null; 
         boolean rtn = false;

         try
         {

                // cssfile accessed as a resource, so must be in the pkg (in src dir).
                InputStream stream = oParser.getClass().getResourceAsStream(cssfile);

                 // overwrites and existing file contents
                 out = new FileOutputStream("log.txt");

                 if (out != null)
                 {
                     //log file
                     ps = new PrintStream( out );
                     System.setErr(ps); //redirects stderr to the log file as well

                 } else {

                     return rtn; 

                }


                InputSource source = new InputSource(new InputStreamReader(stream));
                CSSOMParser parser = new CSSOMParser();
                // parse and create a stylesheet composition
                CSSStyleSheet stylesheet = parser.parseStyleSheet(source, null, null);

                //ANY ERRORS IN THE DOM WILL BE SENT TO STDERR HERE!!
                // now iterate through the dom and inspect.

                CSSRuleList ruleList = stylesheet.getCssRules();

                ps.println("Number of rules: " + ruleList.getLength());


               for (int i = 0; i < ruleList.getLength(); i++) 
               {
                 CSSRule rule = ruleList.item(i);
                 if (rule instanceof CSSStyleRule) 
                 {
                     CSSStyleRule styleRule=(CSSStyleRule)rule;
                     ps.println("selector:" + i + ": " + styleRule.getSelectorText());
                     CSSStyleDeclaration styleDeclaration = styleRule.getStyle();


                     for (int j = 0; j < styleDeclaration.getLength(); j++) 
                     {
                          String property = styleDeclaration.item(j);
                          ps.println("property: " + property);
                          ps.println("value: " + styleDeclaration.getPropertyCSSValue(property).getCssText());
                          ps.println("priority: " + styleDeclaration.getPropertyPriority(property));   
                     }



                  }// end of StyleRule instance test
                } // end of ruleList loop

               if (out != null) out.close();
               if (stream != null) stream.close();
               rtn = true;
            }
            catch (IOException ioe)
            {
                System.err.println ("IO Error: " + ioe);
            }
            catch (Exception e)
            {
                System.err.println ("Error: " + e);

            }
            finally
            {
                if (ps != null) ps.close(); 
            }

            return rtn;

    }

}

【讨论】:

  • 嗨,吉恩,感谢您提供的信息。我一直在使用 CSSParser 并没有太多问题 - 除了两个小烦恼:1)如果存在无法识别或格式错误的规则,则解析器似乎会在整个文件上出错 - 而不是仅仅删除那条规则。显然,对于真实的 css,这种情况发生了很多。另外,我认为 cmets 存在一个错误:多行 cmets 似乎导致所有后续 css 被删除到下一个评论。你注意到了吗?
  • 嗨,Richard,我刚刚开始使用 CSSParser。我还没有注意到丢失的 cmets 问题——我正在尝试找到一个 stackoverflow.com/questions/1853379/…> 来解决它删除 IE hacks 的问题,目前。你自己有这个问题的经验吗?
  • 不是真的 - 虽然可能是我看到的一些呕吐的原因。在不知道你在做什么的情况下,我建议在解析之前对每个 css 文件进行一些预处理。您也许可以为 IE hack 设置一些正则表达式并将它们删除?
【解决方案2】:

一个用于在 Java 中读写 CSS2 和 CSS3 文件的 CSS 库是 ph-css,来自 https://github.com/phax/ph-css 它基于 JavaCC 语法,支持 CSS2 和 CSS3,还可以解析 HTML 样式属性。

  • 它支持最常见的不符合规范的黑客“*”、“_”和“$”
  • 它支持 CSS 数学 - calc() 表达式
  • 支持@page规则
  • 它支持 CSS3 媒体查询
  • 支持@viewport 规则
  • 支持@keyframes 规则
  • 它支持 @supports 规则 - 相当新
  • 它支持@namespace 规则
  • 您可以获得不同元素的源位置信息(开始和结束的行 + 列号 - 既适用于标签,也适用于完整的构造)

自 2013 年 5 月 21 日起,还提供 JDK 1.5 版本,这让 Android 开发更有趣

【讨论】:

  • 我确实使用了它,并且自从提出问题以来,它确实发展得很好。不错的 API,访问者只获取您需要的元素,只是缺少一些文档(但 API 文档相当不错)。推荐。
  • 这个好项目的文档很差,真是太浪费了。稍加努力,这可能会成为一个更受欢迎的项目。
  • 这对我来说是最好的
  • 同时 Apache JMeter 3 也在使用这个库 :)
【解决方案3】:

我需要一个用于自己的项目的 CSS 解析器,但我发现“CSSParser”太乏味且不灵活,无法使用(但那可能只是我自己),所以我最终编写了自己的简单但实用的 CSS 解析器.

如果您愿意,请随意使用它:-)

OSBCP CSS Parser

【讨论】:

  • 我快速查看了您的项目,您的解析器似乎非常强大且功能强大。我正在认真考虑在我的一个项目中使用它。有什么我需要知道的问题吗?另外,能否在内存中修改 CSS 规则,然后再次保存到 CSS 文件中?谢谢。
  • 是的。它将规则解析为规则列表,可以对其进行修改,然后使用 toString() 将其写回字符串/文件。我希望这能回答你的问题。
  • 谢谢。顺便说一句,我正在使用它,它对我来说非常有用。
  • 我可以用它来开始编写一个 scss 解析器还是它已经可以与 scss 一起使用?
  • 如果您想要做的不是测试 CSS 是否有效,这是唯一有意义的解析器。
【解决方案4】:

对 cssparser.sourcefourge.net 的补充,

眼镜蛇:

http://lobobrowser.org/cobra.jsp

【讨论】:

  • 非常感谢我去看看
  • 也使用旧的 CSSParser 项目
【解决方案5】:

在此处查看 SAC 及其实现:http://www.w3.org/Style/CSS/SAC/

CSSParser 有点过时了

【讨论】:

    【解决方案6】:

    jStyleParser 正好提供了这个功能。它解析所有引用的样式表并将它们映射到 DOM 树节点。

    【讨论】:

      【解决方案7】:

      如果您使用 CSSParser,因为似乎根本没有文档,并且您可能只想解析 CSS 字符串,例如样式参数中的值,这里是我的简单使用示例:

      import org.junit.Test;
      import org.w3c.css.sac.InputSource;
      import org.w3c.dom.css.CSSRule;
      import org.w3c.dom.css.CSSStyleDeclaration;
      import org.w3c.dom.css.CSSValue;
      
      import com.steadystate.css.parser.CSSOMParser;
      
      public class ParseCssTest {
      
      @Test
      public void testParseStyleDeclaration() throws IOException {
          String cssSample = "margin-top: 0cm; margin-bottom: 0cm; background: #e6e6e6";
          CSSOMParser parser = new CSSOMParser();
          CSSStyleDeclaration o = parser.parseStyleDeclaration(new InputSource(new StringReader(cssSample)));
          assertEquals("margin-top: 0cm; margin-bottom: 0cm; background: rgb(230, 230, 230)", o.toString());
          assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").toString());
          assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").getCssText());
          assertEquals(null, o.getPropertyCSSValue("foo"));
      }
      
      @Test
      public void testParseARule() throws IOException {
          String cssSample = "r1 { margin-top: 0cm; margin-bottom: 0cm; background: #e6e6e6 }";
          CSSOMParser parser = new CSSOMParser();
          CSSRule o = parser.parseRule(new InputSource(new StringReader(cssSample)));
          assertEquals("r1 { margin-top: 0cm; margin-bottom: 0cm; background: rgb(230, 230, 230) }", o.toString());
      }
      
      @Test
      public void parseStyleDeclarationWithAdvancedTests() throws IOException {
          String cssSample = "margin-top: 0 cm; margin-bottom: 0cm; background: #e6e6e6";
          CSSOMParser parser = new CSSOMParser();
          CSSStyleDeclaration o = parser.parseStyleDeclaration(new InputSource(new StringReader(cssSample)));
          assertEquals("margin-top: 0 cm; margin-bottom: 0cm; background: rgb(230, 230, 230)", o.toString());
      
          assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").toString());
          assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").getCssText());
          assertEquals(CSSValue.CSS_VALUE_LIST, o.getPropertyCSSValue("margin-top").getCssValueType());
      
          assertEquals("0 cm", o.getPropertyCSSValue("margin-top").toString());
          assertEquals("0 cm", o.getPropertyCSSValue("margin-top").getCssText());
          assertEquals(CSSValue.CSS_VALUE_LIST, o.getPropertyCSSValue("margin-top").getCssValueType());
      }
      }
      

      CSSParser 的一大优势是它目前在 Maven 中。因此,如果您寻找一些相当简单且直接可用的东西,CSSParser 似乎是一个不错的选择。

      注意:它会自动将颜色从十六进制格式转换为 rgb() 格式,但对单位大小没有帮助,它将它们视为值列表!不太好。

      【讨论】:

        【解决方案8】:

        我刚刚推出了自己的用于 Java 的 CSS 流解析器,可在 github 上找到。该解析器的不同之处包括:

        • 它是一个流解析器,因此解析器处理程序将在每个项目被解析后立即收到所有新内容的通知
        • 完全支持所有当前记录的 At-Rules
        • 自定义类 TokenSequenceToken 简化了处理选择器等的流程。
        • 易于使用和理解
        • 可用于验证或更高级的应用程序
        • 可扩展:旨在能够处理对 CSS 定义的更改。

        【讨论】:

          猜你喜欢
          • 2011-07-06
          • 1970-01-01
          • 2013-02-17
          • 2010-10-06
          • 1970-01-01
          • 2011-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多