使用Xpath查询HTML in iOS

Use Xpath to query HTML in iOS

我正在努力查询 HTML <select><option> 的文本和值 2 天,但到目前为止没有运气。

我有一个html文档,select的内容如下,

<select name="ctl00$ContentPlaceHolder1$ddlAreas" id="ctl00_ContentPlaceHolder1_ddlAreas">
    <option value="01">Area1</option>
    <option value="02">Area2</option>
    <option value="03">Area3</option>
    <option value="04">Area4</option>
</select>

我正在使用 xPath 表达式检索:

//select[@id=\"ctl00_ContentPlaceHolder1_ddlAreas\"]/option/text() 

选项的内部文字,如Area1, 2, 3, 4...

我正在使用 xPath 表达式来检索

//select[@id=\"ctl00_ContentPlaceHolder1_ddlAreas\"]/option/@value 

选项的值,01、02、03、04...

实际上,我希望将内部文本和值都提取出来,并用分隔符组合,例如“#”。我想要的输出,

Area1#01,
Area2#02
Area3#03
Area4#04....

我尝试使用方法concat()

//select[@id=\"ctl00_ContentPlaceHolder1_ddlAreas\"]/option/[concat(/text(),\"#\",/@value)]

但是好像只返回了第一个选项-Area1,而且根本没有分隔符。

如果有人想出解决方案,我将不胜感激。

您可以使用诸如 tfhpple 的 xml/html 解析器来解析您的 html

https://github.com/topfunky/hpple

#import "TFHpple.h"

NSString * html = @"<select name=\"ctl00$ContentPlaceHolder1$ddlAreas\" id=\"ctl00_ContentPlaceHolder1_ddlAreas\"><option value=\"01\">Area1</option><option value=\"02\">Area2</option><option value=\"03\">Area3</option><option value=\"04\">Area4</option></select>";

NSData* data = [html dataUsingEncoding:NSUTF8StringEncoding];

TFHpple *parser = [TFHpple hppleWithHTMLData:data];
NSString *optionPath = @"//select[@id=\"ctl00_ContentPlaceHolder1_ddlAreas\"]/option";
NSArray *optionNodes = [parser searchWithXPathQuery:optionPath];

for (TFHppleElement *element in optionNodes) {

    NSDictionary * attributes = [element attributes];

    if ([attributes objectForKey:@"value"]){

        NSString * str = [NSString stringWithFormat:@"%@#%@",element.text, [attributes objectForKey:@"value"]];

        NSLog(@"%@", str);

    }

}

输出是

区域1#01

区域2#02

Area3#03

Area4#04

Could there be a better solution that retrievs both the text and value one time via an XPath expression?

不,这不能用单个 XPath 1.0 表达式来完成。之所以使用concat()的解决方案:

concat(//select[@id = 'ctl00_ContentPlaceHolder1_ddlAreas']/option/text(),"#",//select[@id = 'ctl00_ContentPlaceHolder1_ddlAreas']/option/@value)

只有returns第一个结果:

Area1#01

XPath 1.0 中的函数期望将单个节点作为参数,当传递一系列节点时,仅处理第一个节点而忽略所有其余节点。此外,在 XPath 1.0 中,函数在路径表达式中实际上不能 steps

在 XPath 2.0 中你可以

//select[@id = 'ctl00_ContentPlaceHolder1_ddlAreas']/option/concat(.,'#',@value)

concat() 将依次应用于每个 option 元素。


总而言之,纯 XPath 1.0 无法做到这一点。使用 XPath 表达式检索所有 option 元素节点,并在 XPath 的 外部 进一步处理它们,在您嵌入 XPath 的高级语言中 - 如 myte.