利用ph-css解析css
前言
- 最近项目要求解析html,用jsoup可以很好的完成解析,可是将style标签中的文本读取出来后,对于css文本没有提供解析方法,更何况还有外联样式.css文件,这样就很难对css进行操作。
- 在github上找到ph-css这个开源项目之后,在网上却没有一点点的中文资料,只好硬着头皮看ph-css的全英文的readme。希望这篇文章可以帮助大家减少学习的时间。
准备
- maven依赖
<groupId>com.helger</groupId>
<artifactId>ph-css</artifactId>
<version>6.2.3</version>
使用
- 专有名词
以下css文本为例
#div1{
background-image:url('1.png')
height:100px;
width:100px;
}
#div2{
background-image:url('2.png')
height:100px;
width:100px;
}
styleSheet:以上css文本全部内容
#div1{
background-image:url('1.png')
height:100px;
width:100px;
}
#div2{
background-image:url('2.png')
height:100px;
width:100px;
}
rule:每个选择器中的内容
#div1{
background-image:url('1.png')
height:100px;
width:100px;
}
declaration:每个样式声明
background-image:url('1.png')
expression:每个样式内容
url('1.png')
- 读取css
//从String中读取
CascadingStyleSheet styleSheet = CSSReader.readFromString("", ECSSVersion.CSS30);
//从File中读取
CascadingStyleSheet styleSheet = CSSReader.readFromFile(new File(""), StandardCharsets.UTF_8, ECSSVersion.CSS30);
- 获取rule
因为css中含有带@的动态选择器,所以ph-css中定义了多种rule,都提供方法获取,如下:
因为@中可能存在嵌套,很难解析,所以本人将以上rule分为普通的styleRule和其他rule,分两种情况处理:List<ICSSTopLevelRule> rules = styleSheet.getAllRules(); for (ICSSTopLevelRule rule : rules) { if (rule instanceof CSSStyleRule){ //处理styleRule } if(!(rule instanceof CSSStyleRule)) { //处理其他rule } }
- 处理styleRule及expression
这里以替换background-image为例,其他rule直接replace就行了
有人也许会问处理styleRule为什么不能也用replace,这是因为replace的算法十分耗时,而且利用ph-css可以把解析css从项目中抽离解耦,而其他rule由于css的复杂程度不可控,只能做单独处理。当然有什么其他好的方法或者工具也可以告诉我。//处理styleRule CSSStyleRule styleRule = (CSSStyleRule) rule; //也有获取所有declaration的方法 CSSDeclaration cssDeclaration = styleRule.getDeclarationOfPropertyName("background-image"); if (cssDeclaration != null) { CSSExpression expression = cssDeclaration.getExpression(); expression.removeAllMembers(); expression.addTermSimple("url('11.png')"); }
- 另
- rule和expression提供getAsCSSString方法转化为字符串。
- 将ph-css源码下载下来会报错,因为它有几个类是通过脚本创建的。