【发布时间】:2009-10-03 12:12:04
【问题描述】:
我正在寻找 Java 中的 CSS 解析器。特别是我的要求是,对于 HTML 文档中的给定节点/元素,能够从解析器中询问/获取该元素的 css 样式。
我知道有 W3C SAC 接口和基于此的一两个实现 - 但教程/示例似乎不存在。
非常感谢任何正确方向的帮助/点。
谢谢
【问题讨论】:
-
@adatapost:将您的回复重新发布为“答案”而不是“评论”
我正在寻找 Java 中的 CSS 解析器。特别是我的要求是,对于 HTML 文档中的给定节点/元素,能够从解析器中询问/获取该元素的 css 样式。
我知道有 W3C SAC 接口和基于此的一两个实现 - 但教程/示例似乎不存在。
非常感谢任何正确方向的帮助/点。
谢谢
【问题讨论】:
我用过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;
}
}
【讨论】:
一个用于在 Java 中读写 CSS2 和 CSS3 文件的 CSS 库是 ph-css,来自 https://github.com/phax/ph-css 它基于 JavaCC 语法,支持 CSS2 和 CSS3,还可以解析 HTML 样式属性。
自 2013 年 5 月 21 日起,还提供 JDK 1.5 版本,这让 Android 开发更有趣
【讨论】:
我需要一个用于自己的项目的 CSS 解析器,但我发现“CSSParser”太乏味且不灵活,无法使用(但那可能只是我自己),所以我最终编写了自己的简单但实用的 CSS 解析器.
如果您愿意,请随意使用它:-)
【讨论】:
【讨论】:
在此处查看 SAC 及其实现:http://www.w3.org/Style/CSS/SAC/
CSSParser 有点过时了
【讨论】:
jStyleParser 正好提供了这个功能。它解析所有引用的样式表并将它们映射到 DOM 树节点。
【讨论】:
如果您使用 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() 格式,但对单位大小没有帮助,它将它们视为值列表!不太好。
【讨论】:
我刚刚推出了自己的用于 Java 的 CSS 流解析器,可在 github 上找到。该解析器的不同之处包括:
TokenSequence 和 Token 简化了处理选择器等的流程。【讨论】: