Dec*_*ler 7 algorithm logic xpath predicate css-selectors
我正在为xpath 1转换器创建一个CSS选择器,而我最挣扎的一个细节就是找到An+B微语法的简洁替代品.
由于我是为xpath 1实现它并且以尽可能通用的方式实现它,因此我生成的谓词必须遵守一些约束:
我(相信我)不能使用position(),因为这取决于可能在前的谓词.
所有*-of-type伪类等价物都将由宿主语言中的外部函数生成,因为我认为没有办法根据xpath 1中前一个上下文节点的名称构建谓词.
例如,硬编码li:first-of-type为
//li[count(preceding-sibling::li) = 0]
Run Code Online (Sandbox Code Playgroud)
很好.但动态编码*:first-of-type就像
//*[count(preceding-sibling::*[name()=name(.)]) = 0]
<!-- this is probably silly anyway -->
Run Code Online (Sandbox Code Playgroud)
我相信在xpath 1中是不可能的.
所以,这是我提出的"模板"谓词nth-of-type(An+B),宿主语言将填充缺少的值:
<!--
$A represents the step (A) I will insert
$Am represents "mod $A" I will insert if $A != 0
$B represents the offset (B) I will insert
$E represents the element name I will insert
$O represents the operator I will insert: <= if $A is negative, else >=
-->
[count(preceding-sibling::$E) + 1 - $B $O 0 and
(count(preceding-sibling::$E) + 1 - $B) $Am = 0]
Run Code Online (Sandbox Code Playgroud)
li:nth-of-type(2n+3) 因此会变成:
<!--
$A (step) = 2
$Am (mod step) = mod $A = mod 2
$B (offset) = 3
$E (element name) = li
$O (comparison operator) = >=
-->
[count(preceding-sibling::li) + 1 - 3 >= 0 and
(count(preceding-sibling::li) + 1 - 3) mod 2 = 0]
Run Code Online (Sandbox Code Playgroud)
li:nth-of-type(-2n+3) 因此会变成:
<!--
$A (step) = -2
$Am (mod step) = mod $A = mod -2
$B (offset) = 3
$E (element name) = li
$O (comparison operator) = <=
-->
[count(preceding-sibling::li) + 1 - 3 <= 0 and
(count(preceding-sibling::li) + 1 - 3) mod -2 = 0]
Run Code Online (Sandbox Code Playgroud)
li:nth-of-type(3) 因此会变成:
<!--
$A (step) = 0
$Am (mod step) = absent
$B (offset) = 3
$E (element name) = li
$O (comparison operator) = >=
first line seems redundant now
-->
[count(preceding-sibling::li) + 1 - 3 >= 0 and
(count(preceding-sibling::li) + 1 - 3) = 0]
Run Code Online (Sandbox Code Playgroud)
...等等.
如你所见,它有点笨拙.我最好创建一个很好的紧凑的单线性谓词,没有看似冗余的位,并且对变量替换的需求最少(特别是比较运算符和与步骤相关的mod计算).
有没有更简洁的方法来结合An+B我上面显示的(步进和偏移)功能?