NSXMLParser解析XML&获取XPath

计算器页面

计算器页面
// 描述iPhone计算器页面的xml
<?xml version="1.0" encoding="UTF-8"?>
<XCUIElementTypeApplication type="XCUIElementTypeApplication" name="计算器" label="计算器" enabled="true" visible="true" x="0" y="0" width="414" height="736">
    <XCUIElementTypeWindow type="XCUIElementTypeWindow" enabled="true" visible="true" x="0" y="0" width="414" height="736">
        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="0" width="414" height="736">
            <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="3333" name="结果" label="结果" enabled="true" visible="true" x="0" y="20" width="414" height="219"/>
            <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="239" width="414" height="497">
                <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="239" width="414" height="497">
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="清除" label="清除" enabled="true" visible="true" x="16" y="239" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="正数负数" label="正数负数" enabled="true" visible="true" x="115" y="239" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="百分比" label="百分比" enabled="true" visible="true" x="214" y="239" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="除" label="除" enabled="true" visible="true" x="313" y="239" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="7" label="7" enabled="true" visible="true" x="16" y="338" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="8" label="8" enabled="true" visible="true" x="115" y="338" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="9" label="9" enabled="true" visible="true" x="214" y="338" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="乘" label="乘" enabled="true" visible="true" x="313" y="338" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="4" label="4" enabled="true" visible="true" x="16" y="437" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="5" label="5" enabled="true" visible="true" x="115" y="437" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="6" label="6" enabled="true" visible="true" x="214" y="437" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="减" label="减" enabled="true" visible="true" x="313" y="437" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="1" label="1" enabled="true" visible="true" x="16" y="536" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="2" label="2" enabled="true" visible="true" x="115" y="536" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="3" label="3" enabled="true" visible="true" x="214" y="536" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="加" label="加" enabled="true" visible="true" x="313" y="536" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="0" label="0" enabled="true" visible="true" x="16" y="635" width="184" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="小数点" label="小数点" enabled="true" visible="true" x="214" y="635" width="85" height="85"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="等于" label="等于" enabled="true" visible="true" x="313" y="635" width="85" height="85"/>
                </XCUIElementTypeOther>
            </XCUIElementTypeOther>
        </XCUIElementTypeOther>
    </XCUIElementTypeWindow>
    <XCUIElementTypeWindow type="XCUIElementTypeWindow" enabled="true" visible="false" x="0" y="0" width="414" height="736">
        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="0" width="414" height="736">
            <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="736" width="414" height="226"/></XCUIElementTypeOther>
    </XCUIElementTypeWindow>
    <XCUIElementTypeWindow type="XCUIElementTypeWindow" enabled="true" visible="true" x="0" y="0" width="414" height="736">
        <XCUIElementTypeStatusBar type="XCUIElementTypeStatusBar" enabled="true" visible="true" x="0" y="0" width="414" height="20">
            <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="0" width="414" height="20"/>
            <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="0" width="414" height="20">
                <XCUIElementTypeOther type="XCUIElementTypeOther" name="信号强度:4(共 4 格)" label="信号强度:4(共 4 格)" enabled="true" visible="true" x="6" y="0" width="16" height="20"/>
                <XCUIElementTypeOther type="XCUIElementTypeOther" value="SSID" name="3 格(共 3 格无线局域网信号)" label="3 格(共 3 格无线局域网信号)" enabled="true" visible="true" x="25" y="0" width="14" height="20"/>
                <XCUIElementTypeOther type="XCUIElementTypeOther" name="09:41" label="09:41" enabled="true" visible="true" x="192" y="0" width="34" height="20"/>
                <XCUIElementTypeOther type="XCUIElementTypeOther" name="方向已锁定" label="方向已锁定" enabled="true" visible="true" x="306" y="0" width="12" height="20"/>
                <XCUIElementTypeOther type="XCUIElementTypeOther" name="闹钟" label="闹钟" enabled="true" visible="true" x="324" y="0" width="10" height="20"/>
                <XCUIElementTypeOther type="XCUIElementTypeOther" name="电池电量:100%, 使用交流电源" label="电池电量:100%, 使用交流电源" enabled="true" visible="true" x="340" y="0" width="69" height="20"/>
                <XCUIElementTypeOther type="XCUIElementTypeOther" name="电池电量:100%" label="电池电量:100%" enabled="true" visible="false" x="340" y="0" width="31" height="20"/></XCUIElementTypeOther>
        </XCUIElementTypeStatusBar>
    </XCUIElementTypeWindow>
</XCUIElementTypeApplication>
//
//  ViewController.m
//  XML解析
//
//  Created by YPF on 2018/8/16.
//  Copyright © 2018年 原鹏飞. All rights reserved.
//

#import "ViewController.h"

@interface ViewController() <NSXMLParserDelegate>

@property (nonatomic, assign) NSInteger x;
@property (nonatomic, assign) NSInteger y;

@property (nonatomic, copy) NSString *xmlStr;
@property (nonatomic, copy) NSString *xpath;
@property (nonatomic, strong) NSMutableArray *pathArrM;
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *qualifiedElementArrM;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.
    
    _xmlStr = @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<XCUIElementTypeApplication type=\"XCUIElementTypeApplication\" name=\"计算器\" label=\"计算器\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"0\" width=\"414\" height=\"736\">\n  <XCUIElementTypeWindow type=\"XCUIElementTypeWindow\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"0\" width=\"414\" height=\"736\">\n    <XCUIElementTypeOther type=\"XCUIElementTypeOther\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"0\" width=\"414\" height=\"736\">\n      <XCUIElementTypeStaticText type=\"XCUIElementTypeStaticText\" value=\"77777\" name=\"结果\" label=\"结果\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"20\" width=\"414\" height=\"219\"\/>\n      <XCUIElementTypeOther type=\"XCUIElementTypeOther\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"239\" width=\"414\" height=\"497\">\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"239\" width=\"414\" height=\"497\">\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"清除\" label=\"清除\" enabled=\"true\" visible=\"true\" x=\"16\" y=\"239\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"正数负数\" label=\"正数负数\" enabled=\"true\" visible=\"true\" x=\"115\" y=\"239\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"百分比\" label=\"百分比\" enabled=\"true\" visible=\"true\" x=\"214\" y=\"239\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"除\" label=\"除\" enabled=\"true\" visible=\"true\" x=\"313\" y=\"239\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"7\" label=\"7\" enabled=\"true\" visible=\"true\" x=\"16\" y=\"338\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"8\" label=\"8\" enabled=\"true\" visible=\"true\" x=\"115\" y=\"338\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"9\" label=\"9\" enabled=\"true\" visible=\"true\" x=\"214\" y=\"338\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"乘\" label=\"乘\" enabled=\"true\" visible=\"true\" x=\"313\" y=\"338\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"4\" label=\"4\" enabled=\"true\" visible=\"true\" x=\"16\" y=\"437\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"5\" label=\"5\" enabled=\"true\" visible=\"true\" x=\"115\" y=\"437\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"6\" label=\"6\" enabled=\"true\" visible=\"true\" x=\"214\" y=\"437\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"减\" label=\"减\" enabled=\"true\" visible=\"true\" x=\"313\" y=\"437\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"1\" label=\"1\" enabled=\"true\" visible=\"true\" x=\"16\" y=\"536\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"2\" label=\"2\" enabled=\"true\" visible=\"true\" x=\"115\" y=\"536\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"3\" label=\"3\" enabled=\"true\" visible=\"true\" x=\"214\" y=\"536\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"加\" label=\"加\" enabled=\"true\" visible=\"true\" x=\"313\" y=\"536\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"0\" label=\"0\" enabled=\"true\" visible=\"true\" x=\"16\" y=\"635\" width=\"184\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"小数点\" label=\"小数点\" enabled=\"true\" visible=\"true\" x=\"214\" y=\"635\" width=\"85\" height=\"85\"\/>\n          <XCUIElementTypeButton type=\"XCUIElementTypeButton\" name=\"等于\" label=\"等于\" enabled=\"true\" visible=\"true\" x=\"313\" y=\"635\" width=\"85\" height=\"85\"\/>\n        <\/XCUIElementTypeOther>\n      <\/XCUIElementTypeOther>\n    <\/XCUIElementTypeOther>\n  <\/XCUIElementTypeWindow>\n  <XCUIElementTypeWindow type=\"XCUIElementTypeWindow\" enabled=\"true\" visible=\"false\" x=\"0\" y=\"0\" width=\"414\" height=\"736\">\n    <XCUIElementTypeOther type=\"XCUIElementTypeOther\" enabled=\"true\" visible=\"false\" x=\"0\" y=\"0\" width=\"414\" height=\"736\">\n      <XCUIElementTypeOther type=\"XCUIElementTypeOther\" enabled=\"true\" visible=\"false\" x=\"0\" y=\"736\" width=\"414\" height=\"226\"\/>\n    <\/XCUIElementTypeOther>\n  <\/XCUIElementTypeWindow>\n  <XCUIElementTypeWindow type=\"XCUIElementTypeWindow\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"0\" width=\"414\" height=\"736\">\n    <XCUIElementTypeStatusBar type=\"XCUIElementTypeStatusBar\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"0\" width=\"414\" height=\"20\">\n      <XCUIElementTypeOther type=\"XCUIElementTypeOther\" enabled=\"true\" visible=\"false\" x=\"0\" y=\"0\" width=\"414\" height=\"20\"\/>\n      <XCUIElementTypeOther type=\"XCUIElementTypeOther\" enabled=\"true\" visible=\"true\" x=\"0\" y=\"0\" width=\"414\" height=\"20\">\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" name=\"信号强度:4(共 4 格)\" label=\"信号强度:4(共 4 格)\" enabled=\"true\" visible=\"true\" x=\"6\" y=\"0\" width=\"16\" height=\"20\"\/>\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" value=\"SSID\" name=\"3 格(共 3 格无线局域网信号)\" label=\"3 格(共 3 格无线局域网信号)\" enabled=\"true\" visible=\"true\" x=\"25\" y=\"0\" width=\"14\" height=\"20\"\/>\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" name=\"09:41\" label=\"09:41\" enabled=\"true\" visible=\"true\" x=\"192\" y=\"0\" width=\"34\" height=\"20\"\/>\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" name=\"方向已锁定\" label=\"方向已锁定\" enabled=\"true\" visible=\"true\" x=\"306\" y=\"0\" width=\"12\" height=\"20\"\/>\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" name=\"闹钟\" label=\"闹钟\" enabled=\"true\" visible=\"true\" x=\"324\" y=\"0\" width=\"10\" height=\"20\"\/>\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" name=\"电池电量:100%, 使用交流电源\" label=\"电池电量:100%, 使用交流电源\" enabled=\"true\" visible=\"true\" x=\"340\" y=\"0\" width=\"69\" height=\"20\"\/>\n        <XCUIElementTypeOther type=\"XCUIElementTypeOther\" name=\"电池电量:100%\" label=\"电池电量:100%\" enabled=\"true\" visible=\"false\" x=\"340\" y=\"0\" width=\"31\" height=\"20\"\/>\n      <\/XCUIElementTypeOther>\n    <\/XCUIElementTypeStatusBar>\n  <\/XCUIElementTypeWindow>\n<\/XCUIElementTypeApplication>\n";
    
    _pathArrM = [[NSMutableArray alloc] init];
}


/**
 懒加载筛选出的控件数组

 @return 筛选结果数组
 */
- (NSMutableArray *)qualifiedElementArrM {
    if (!_qualifiedElementArrM) {
        _qualifiedElementArrM = [[NSMutableArray alloc] init];
    }
    
    return _qualifiedElementArrM;
}


- (IBAction)clickStartBtn:(NSButton *)sender {
    
    // 假设这里判断点(100, 350)对应的是哪个控件
    _x = 100;
    _y = 350;
    
    [self useXMLParserWithData:[self.xmlStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSLog(@"筛选结果:%@", self.qualifiedElementArrM);
    NSLog(@"elementXpath = %@", [self.qualifiedElementArrM.firstObject valueForKey:@"elementXpath"]);
}


- (void)useXMLParserWithData:(NSData *)data {
    
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
    [xmlParser setDelegate:self];
    [xmlParser parse];
}


#pragma mark - NSXMLParserDelegate

/**
 开始解析文档

 @param parser 解析器
 */
- (void)parserDidStartDocument:(NSXMLParser *)parser {
    NSLog(@"开始解析XML文件!");
}


/**
 开始标签

 @param parser 解析器
 @param elementName 元素名称
 @param namespaceURI 命名空间
 @param qName 限定名
 @param attributeDict 属性字典
 */
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
    
    [self.pathArrM addObject:elementName];
    
    if ([elementName isEqualToString:@"XCUIElementTypeButton"]) {
        NSLog(@"找到一个按钮 qualifiedName = %@, attributes = %@", qName, attributeDict);
        
        // 判断x坐标
        if ([attributeDict valueForKey:@"x"].integerValue <= self.x && self.x <= [attributeDict valueForKey:@"x"].integerValue + [attributeDict valueForKey:@"width"].integerValue) {
            
            // 判断y
            if ([attributeDict valueForKey:@"y"].integerValue <= self.y && self.y <= [attributeDict valueForKey:@"y"].integerValue + [attributeDict valueForKey:@"height"].integerValue) {
                
                NSString *elementXpath = [NSString stringWithFormat:@"//%@[@name='%@']", [self.pathArrM componentsJoinedByString:@"/"], attributeDict[@"name"]];
                
                NSDictionary *elementDict = @{@"elementXpath":elementXpath,
                                              @"attributeDict":attributeDict
                                              };
                
                // 加入筛选合格的控件数组
                [self.qualifiedElementArrM addObject:elementDict];
            }
        }
        
    }
    
    if ([elementName isEqualToString:@"XCUIElementTypeStaticText"]) {
        NSLog(@"找到一个文本框 qualifiedName = %@, attributes = %@", qName, attributeDict);
        
        // 判断x坐标
        if ([attributeDict valueForKey:@"x"].integerValue <= self.x && self.x <= [attributeDict valueForKey:@"x"].integerValue + [attributeDict valueForKey:@"width"].integerValue) {
            
            // 判断y
            if ([attributeDict valueForKey:@"y"].integerValue <= self.y && self.y <= [attributeDict valueForKey:@"y"].integerValue + [attributeDict valueForKey:@"height"].integerValue) {
                
                NSString *elementXpath = [NSString stringWithFormat:@"//%@[@name='%@']", [self.pathArrM componentsJoinedByString:@"/"], attributeDict[@"name"]];
                
                NSDictionary *elementDict = @{@"elementXpath":elementXpath,
                                              @"attributeDict":attributeDict
                                              };
                
                // 加入筛选合格的控件数组
                [self.qualifiedElementArrM addObject:elementDict];
            }
        }
    }
    
}


/**
 找到指定的字符串

 @param parser 解析器
 @param string 指定要查找的字符串
 */
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    
}


/**
 结束标签

 @param parser 解析器
 @param elementName 元素名称
 @param namespaceURI 命名空间
 @param qName 限定名
 */
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    NSLog(@"XML解析完成一个元素:elementName = %@,qualifiedName = %@🐶", elementName, qName);
    
    if ([elementName isEqualToString:self.pathArrM.lastObject]) {
        [self.pathArrM removeLastObject];
    }
}


/**
 文档解析结束

 @param parser 解析器
 */
- (void)parserDidEndDocument:(NSXMLParser *)parser {
    
}


#pragma mark - 自带方法

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}


@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值