获取应用于Java中特定HTML类的CSS规则列表



我正在使用CSS Parser来获取属于一个集合HTML类的特定CSS规则。目前,我在网站上有一个CSS规则列表,但我不知道如何获得我想要的规则。

当前代码:

InputSource inputSource = new InputSource("example.com");
CSSOMParser parser = new CSSOMParser(new SACParserCSS3());
ErrorHandler errorHandler = new CSSErrorHandler();
parser.setErrorHandler(errorHandler);
CSSStyleSheet sheet = parser.parseStyleSheet(inputSource, null, null);
CSSRuleList rules = sheet.getCssRules();

我的选择之一是做一个for循环,但我不愿意这样做,因为
a。如果一个页面中有数百条规则,那么速度会很慢。
b。似乎没有任何方法可以获取规则的类名。

如有任何帮助,将不胜感激

添加一个:CSS已经被代码解析了,所以你只需要看看在性能方面可以接受的选择器。

添加b:CSSStyleRule接口缺少方法getSelectors(),但CSSStyleRuleImpl有。所以你可以尝试一下:

scanRules(rules, name -> name.contains("e"), 
(names, rule) -> System.out.println(
new TreeSet<>(names) + " --> " + rule.getCssText()));

使用递归辅助方法

// scan CSS rules including rules contained in media rules 
void scanRules(CSSRuleList rules, Predicate<String> classNameTest,
BiConsumer<Set<String>, CSSStyleRule> ruleAction) {
for (int ri = 0; ri < rules.getLength(); ri++) {
CSSRule rule = rules.item(ri);
if (rule.getType() == CSSRule.MEDIA_RULE) {
CSSMediaRule mr = (CSSMediaRule) rule;
scanRules(mr.getCssRules(), classNameTest, ruleAction);
} else if (rule.getType() == CSSRule.STYLE_RULE) {
CSSStyleRuleImpl styleRule = (CSSStyleRuleImpl) rule;
SelectorList selectors = styleRule.getSelectors();
// if (!styleRule.getSelectorText().contains(".name"))
//  continue; // selector text test might cause speed up...
for (int si = 0; si < selectors.getLength(); si++) {
Selector selector = selectors.item(si);
Set<String> classNames = classNamesInSelectorMatching(selector, classNameTest);
if (!classNames.isEmpty()) 
ruleAction.accept(classNames, styleRule);
}
}
}
}
// find matching class names in given (potentially complex) selector
Set<String> classNamesInSelectorMatching(Selector selector,
Predicate<String> nameMatches) {
switch (selector.getSelectorType()) {
case Selector.SAC_CHILD_SELECTOR:
case Selector.SAC_DESCENDANT_SELECTOR:
case Selector.SAC_DIRECT_ADJACENT_SELECTOR: {
DescendantSelector ds = (DescendantSelector) selector;
Set<String> set = new HashSet<>();
set.addAll(classNamesInSelectorMatching(ds.getAncestorSelector(), nameMatches));
set.addAll(classNamesInSelectorMatching(ds.getSimpleSelector(), nameMatches));
return set;
}
case Selector.SAC_NEGATIVE_SELECTOR: {
NegativeSelector ns = (NegativeSelector) selector;
return classNamesInSelectorMatching(ns.getSimpleSelector(), nameMatches);
}
case Selector.SAC_CONDITIONAL_SELECTOR: {
ConditionalSelector ns = (ConditionalSelector) selector;
return classNamesInConditionMatching(ns.getCondition(), nameMatches);
}
default:
return Collections.emptySet();
}
}
// find matching class names in given (potentially complex) condition
Set<String> classNamesInConditionMatching(Condition condition,
Predicate<String> nameMatches) {
switch (condition.getConditionType()) {
case Condition.SAC_CLASS_CONDITION: {
AttributeCondition ac = (AttributeCondition) condition;
if (nameMatches.test(ac.getValue()))
return Collections.singleton(ac.getValue());
else
return Collections.emptySet();
}
case Condition.SAC_AND_CONDITION:
case Condition.SAC_OR_CONDITION: {
CombinatorCondition cc = (CombinatorCondition) condition;
Set<String> set = new HashSet<>();
set.addAll(classNamesInConditionMatching(cc.getFirstCondition(), nameMatches));
set.addAll(classNamesInConditionMatching(cc.getSecondCondition(), nameMatches));
return set;
}
case Condition.SAC_NEGATIVE_CONDITION: {
NegativeCondition nc = (NegativeCondition) condition;
return classNamesInConditionMatching(nc.getCondition(), nameMatches);
}
default:
return Collections.emptySet();
}
}

我试过输入https://www.w3.org/2008/site/css/minimum-src.css它似乎对我有用。

最新更新