.css为什么使用这个Nokogiri对象而不是XPath?

时间:2016-11-29 19:32:09

标签: ruby xpath nokogiri

为什么CSS选择器会返回正确的信息,但XPath不会?

source = "<hgroup class='page-header channel post-head' data-channel='tech' data-section='sec0=tech&amp;sec1=index&amp;sec2='><h2>Tech</h2></hgroup>"

doc = Nokogiri::HTML(source)
doc.xpath('//hgroup[case_insensitive_equals(@class,"post-head")]//h2', XpathFunctions.new)
 => [] 

doc.css("hgroup.post-head")[0].css("h2")
 => [#<Nokogiri::XML::Element:0x6c2b824 name="h2" children=[#<Nokogiri::XML::Text:0x6c2b554 "Tech">]>] 

1 个答案:

答案 0 :(得分:1)

假设class做了它的名字所暗示的,那是因为post-head属性不等于class(不区分大小写或不区分大小写),但包含< / em>它。 XPath将doc.xpath('//hgroup[contains(@class, "post-head")]//h2') 属性视为纯字符串,它不会拆分它们并像CSS那样单独处理类。

一个可行的简单XPath将是:

not-post-head

(我已经删除了自定义函数,你需要编写自己的函数来不敏感地执行此操作。)

但这并不完全相同,因为它也会匹配doc.xpath('//hgroup[contains(concat(" ", normalize-space(@class), " "), " post-head ")]//h2') 等类。更完整的XPath将是something like this

var group = new THREE.Group();

noise.seed(23);
var worldWidth = 256, worldDepth = 256;
var data = generateNoise( worldWidth, worldDepth );
var geometry = new THREE.PlaneBufferGeometry( 7500, 7500, worldWidth - 1, worldDepth - 1 );
geometry.rotateX( - Math.PI / 2 );
geometry.computeBoundingBox();

var vertices = geometry.attributes.position.array;

var positions   = []

for ( var i = 0, j = 0, l = vertices.length; i < l; i ++, j += 3 ) {
    vertices [ j + 1 ] =  data[ i ] * 10;

    //check if this coordinate is inside the radius we want to know if can spawn a grass
    // if is inside spawn a plant knowing the height of this position

}

var grass = new THREEx.createGrassTufts(positions)
group.add(grass);

var texture = assets.textures.grass.val;

var material = new THREE.MeshPhongMaterial( { map: texture, shading: THREE.SmoothShading } );

var ground = new THREE.Mesh( geometry, material );
ground.receiveShadow = true;
ground.castShadow = true;

group.add(ground);