XPath查找子元素的父元素

时间:2018-01-30 21:48:25

标签: c# html selenium xpath

我有这样的结构:

Driver.FindElement(By.XPath("//div[contains(@class, 'Container')]/descendant::span[text() = 'Products']"));

由于DOM的行为方式和尝试保持动态,我只能定位包含文本产品的范围。使用类似的东西:

class="ContainerSelectedMenu"

但是,我需要根据该span元素定位cl_device_id device_id = NULL; cl_context context = NULL; cl_command_queue command_queue = NULL; cl_mem memobj , resobj = NULL; cl_program program = NULL; cl_kernel kernel = NULL; cl_platform_id platform_id = NULL; cl_uint ret_num_devices; cl_uint ret_num_platforms; cl_int ret; size_t work_units_per_kernels; int input[10] = {1,2,3,4,5,6,7,8,9,10}; int output[10]; int length = 10 ; FILE *fp; char fileName[] = "/home/tuan/OpenCLPlayaround/hello.cl"; char *source_str; size_t source_size; /* Load the source code containing the kernel*/ fp = fopen(fileName, "r"); if (!fp) { fprintf(stderr, "Failed to load kernel.\n"); exit(1); } source_str = (char*)malloc(0x100000); source_size = fread(source_str,1,0x100000, fp); fclose(fp); ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms); std::cout<<ret<<" code"<<std::endl; ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &ret_num_devices); std::cout<<ret<<" code"<<std::endl; context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret); std::cout<<ret<<" code"<<std::endl; command_queue = clCreateCommandQueue(context, device_id, 0, &ret); //Check Concept of memory memobj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,length * sizeof(int), input, &ret); resobj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, length * sizeof(int), output, &ret); std::cout<<ret<<" code"<<std::endl; program = clCreateProgramWithSource(context,1,(const char**)&source_str, (const size_t*)&source_size, &ret); ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); kernel = clCreateKernel(program, "hello", &ret); ret = clSetKernelArg(kernel,0, sizeof(memobj),(void *)&memobj); ret = clSetKernelArg(kernel,1, sizeof(resobj),(void *)&resobj); ret = clEnqueueTask(command_queue, kernel, 0, NULL,NULL); ret = clEnqueueReadBuffer(command_queue, resobj, CL_TRUE, 0, length* sizeof(int),output, 0, NULL, NULL); for (int i = 0 ; i <10 ; i++) { std::cout<<output[i]<<" "<<std::endl; } return 0; 的div,最佳方法是什么?有点像获取Container的子div的父div然后找到button元素。

2 个答案:

答案 0 :(得分:2)

我已经找到了不同的方法,通过上下往复运行来做到这一点很好,但我现在的偏好是这种方法:

xpath = "//div[contains(@class, 'Container') and descendant::span[text() = 'Products']]//button";

基本上,您将带有text() = 'Products'的后代作为您真正想要的div标记的要求的一部分,即父级。然后,您只需使用//button//button[@class='ContainerSelectedMenu']

即可轻松搜索该按钮

这里你实际上不需要descendant轴,因此可以简化一下:

xpath = "//div[contains(@class, 'Container') and .//span[text() = 'Products']]//button";

英文...

  • 找到div
  • 1。@class包含“容器”和
  • 2。有一个后代span元素,文字为`Products
  • 找到div button
  • 的后代

答案 1 :(得分:2)

一种方法是定位span,然后转到祖先div,然后返回到匹配class的元素...

//span[normalize-space()='Products']/ancestor::div[contains(@class,'Container')]//*[contains(@class,'ContainerSelectedMenu')]

另一种方法是定位div,然后定位span,然后上升两个级别,然后返回到匹配class的元素...

//div[contains(@class,'Container')]//span[normalize-space()='Products']/../../*[contains(@class,'ContainerSelectedMenu')]

另一种方式(类似于@mrfreester)是匹配div,测试span,然后直接转到匹配class的元素...

//div[contains(@class, 'Container') and .//span[normalize-space()='Products']]//*[contains(@class,'ContainerSelectedMenu')]

所有这三个都匹配button