扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
webView主要用于加载html,js之类的web页面,而不是解析xml文件。如果不是web页面,只是activity上的一个控件的xml布局,那么使用View.inflate(this,R.xml.***,null)就可以实现加载了。
创新互联公司专注于漳平网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供漳平营销型网站建设,漳平网站制作、漳平网页设计、漳平网站官网定制、小程序制作服务,打造漳平网络公司原创品牌,更为您提供漳平网站排名全网营销落地服务。
维基上MusicXML的解释是:(英语:Music Extensible Markup Language,音乐扩展标记语言)是一个开放的基于XML的记录西式乐谱的文件格式。该格式是完全自由、开放记录的,并依据W3C社区的许可协议自由使用。
简单的来说,MusicXML其实就是XML,只不过承载的是乐谱信息的XML。在我们需要绘制或者创建六线谱之类的时候,可以通过MusicXML来记录我们需要绘制或者创建的信息。目的是为音乐符号创造一种通用格式。(本文是基于MusicXML 3.0和2.0,所以可能会有一些出入。)因为项目中用到的是吉他谱,就以吉他谱的含义来进行说明和解释。
MusicXML本质也是XML,所以文件上的解析可以按XML的解析来。
XML的解析在iOS里面有两种解析方式,一个SAX解析,一个DOM解析。
SAX解析的特点是逐行进行解析。也就是一边读取一边处理。对于大文件,极大的提高了解析效率。
DOM解析的特点是通过节点解析。需要一次性读取整个XML文件并形成一个节点树,通过遍历树结构可以检索任意XML节点,读取它的属性和值。
比如第三方:GDataXMLNode
在这里我用的SAX解析,具体可以去看下 这里 ,是我之前用来解析MusicXML文档写的。
MusicXML本质上还是XML,所以文件结构是和XML一样的,这个是XML文档所需要的XML声明。声明用的xml版本是1.0和xml传输数据的时候的字符编码。(假如文档里有中文,编码方式不是UTF-8,显示上就会乱码)
这里是说明当前使用的MusicXML版本是什么,标签里面包含的内容就是MusicXML的内容
基本能用到的大多数就是这么多了,更多详细的可以查看MusicXML的 官网文档
绘制的话,看具体的需求了,可以尝试在layer上异步绘制,然后在需要的情况下再渲染到view上。比如用 CAShapeLayer ,轻量,性能又好。
最受欢迎的XML分析器简介:
iPhone最流行的XML解析器,以及每个一简要介绍:
• NSXMLParser是一个SAX解析器SDK中包含的iPhone默认的。 这是写在Objective - C和使用非常简单,但也许没有那么容易,因为DOM模型。
• libxml2的是一个开放源码库,包括iPhone SDK的默认情况下使用。 这是一个基于C的API,所以使用起来可能不如NSXML方便。 该库同时支持DOM和SAX处理。 该处理器的libxml2的SAX特别的酷,因为它有一个能够解析它的独特功能正在读取数据。 例如,你可以从网络上阅读大量的XML文档并显示数据,您正在阅读它给用户,而你还在下载。
• TBXML是一个轻量级的DOM XML解析器设计得尽可能快,而资源消耗少的内存。 它节省了验证时间不执行,不支持XPath和由被只读 - 即你可以阅读它的XML,但是你不能再修改XML和写回来。
• TouchXML是NSXML风格的DOM的XML解析器的iPhone。 TBXML一样,它也是只读的,但它不像TBXML支持XPath。
• KissXML是另一个NSSXML风格的DOM XML解析器的iPhone,其实TouchXML的基础上。 主要区别是KissXML还支持编辑和编写XML以及阅读。
• TinyXML的是一个小型的C -基于DOM的XML解析器头只包含4个C文件和两个。 它同时支持读取和编写XML文件,但它不支持自己的XPath。 但是,您可以使用相关的库 - 该TinyXPath - 。
• GDataXML是另一个NSXML风格的DOM XML解析器的iPhone,谷歌开发作为图书馆的一部分,他们的Objective - C的客户端。 短短的m文件和一个头组成,它同时支持阅读和编写XML文档和XPath查询。
首先说一下,在IOS中XML解析和在Android中的SAX或者Pull解析差别不大,都是基于事件的解析方式。
首先,定义一个对象来表示XML的文档结构
XMLElement.h
#import Foundation/Foundation.h
@interface XMLElement : NSObject
// 标签名称
@property (nonatomic,strong) NSString *name;
// 标签的文本(注意在上一级标签和下一级标签之间室友文本的)
@property (nonatomic,strong) NSString *text;
// 标签的属性
@property (nonatomic,strong) NSDictionary *attributes;
// 子标签集合
@property (nonatomic,strong) NSMutableArray *subElements;
// 上一级标签
@property (nonatomic,strong) XMLElement *parent;
@end
XMLElement.m
#import "XMLElement.h"
@implementation XMLElement
@synthesize name,text,attributes,subElements,parent;
-(NSMutableArray *) subElements
{
if(subElements == nil){
subElements = [[NSMutableArray alloc]init];
}
return subElements;
}
@end
XML文件的内容放在/Supporting File/的Group下面。名称为person.xml
?xml version="1.0" encoding="UTF-8"?
root
person id="1"
firstNamezhang/firstName
lastNamesansan/lastName
age21/age
/person
person id="2"
firstNameli/firstName
lastNamesisisi/lastName
age31/age
/person
/root
解析的ViewController.h
#import UIKit/UIKit.h
#import "XMLElement.h"
@interface ViewController : UIViewController NSXMLParserDelegate
// 解析器对象
@property (nonatomic,strong) NSXMLParser *parser;
// 根元素
@property (nonatomic,strong) XMLElement *rootElement;
// 当前的元素
@property (nonatomic,strong) XMLElement *currentElementPointer;
@end
解析的ViewController.m
#import "ViewController.h"
#import "UIColor+ColorWithARGB.h"
@interface ViewController ()
@end
@implementation ViewController
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self != nil){
self.title = @"XML解析";
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor r:0xA5 g:0xA5 b:0x52];
NSString *xmlFilePath = [[NSBundle mainBundle]pathForResource:@"person" ofType:@"xml"];
NSData *data = [[NSData alloc]initWithContentsOfFile:xmlFilePath];
self.parser = [[NSXMLParser alloc]initWithData:data];
self.parser.delegate = self;
if([self.parser parse]){
NSLog(@"The XML is Parsed");
NSMutableString *str = [[NSMutableString alloc]init];
[str appendFormat:@"%@\n",self.rootElement.name];
NSMutableArray *subs = self.rootElement.subElements;
for(int i = 0;i [subs count];i++){
XMLElement *personElement = [subs objectAtIndex:i];
[str appendFormat:@"\tname:%@",personElement.name];
[str appendFormat:@",text:%@\n",personElement.text];
NSArray *subPersonElements = personElement.subElements;
for(int j = 0;j [subPersonElements count];j++){
XMLElement *subElement = [subPersonElements objectAtIndex:j];
[str appendFormat:@"\t\tname:%@",subElement.name];
[str appendFormat:@",text:%@\n",subElement.text];
}
}
NSLog(@"======解析结果:%@" ,str);
}else{
NSLog(@"Failed to parse the XML");
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// 文档开始
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
self.rootElement = nil;
self.currentElementPointer = nil;
}
// 文档结束
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
self.currentElementPointer = nil;
}
// 元素开始
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if(self.rootElement == nil){
self.rootElement = [[XMLElement alloc]init];
self.currentElementPointer = self.rootElement;
}else{
XMLElement *newElement = [[XMLElement alloc]init];
newElement.parent = self.currentElementPointer;
[self.currentElementPointer.subElements addObject:newElement];
self.currentElementPointer = newElement;
}
self.currentElementPointer.name = elementName;
self.currentElementPointer.attributes = attributeDict;
NSLog(@"name:%@" , elementName);
}
// 元素结束
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
self.currentElementPointer = self.currentElementPointer.parent;
NSLog(@"end name:%@" , elementName);
}
// 解析文本,会多次解析,每次只解析1000个字符,如果多月1000个就会多次进入这个方法
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if([self.currentElementPointer.text length] 0){
self.currentElementPointer.text = [self.currentElementPointer.text stringByAppendingString:string];
}else{
self.currentElementPointer.text = [NSMutableString stringWithString:string];
}
NSLog(@"string:%@" , string);
}
@end
NSString *soapStr = [NSString stringWithFormat:@"?xml version=\"1.0\" encoding=\"utf-8\"?\
soap:Envelope xmlns:xsi = \"htttp://www.网址.com"\
xmlns:soap = \"http://网址\"\
soap:header\
/soap:header\
soap:Body\
// 这中间基本就是要写的参数,在Body 之间就是参数
/soap:Body\
/soap:Envelope"];
NSURL *url=[NSURL URLWithString:@"你自己wsdl文档中对应的endpoint address"];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
// 访问方式[request setHTTPMethod:@"POST"];
// 设置请求头(请求头也可以不设置,前两个设不设置都一样,应该默认的,但是SOAPAction我怎么都设置不对,不设置也可以,干脆不设置了)
// [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];// [request addValue:[NSString stringWithFormat:@"%zd", soapStr.length] forHTTPHeaderField:@"Content-Length"];
// [request addValue:@"nameSpace/methodName" forHTTPHeaderField:@"SOAPAction"];
// body内容 [request setHTTPBody:[soapStr dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"进入成功回调Session-----结果:%@----请求地址:%@", result, response.URL);
if (error) {
NSLog(@"Session----失败----%@", error.localizedDescription);
}
}];
[task resume];
// 传入一个字典只有唯一(key - value)的数组,
// eg: NSArray *array = @[@{@"addr":@"777"},@{@"999":@"666"},@{@"000":@"111"}];
+ (NSString*)convertDicArrayToXML:(NSArray*)arrayandElement:(NSString*)element {
if (array.count=0) {
return nil ;
}
NSMutableString *mString = [NSMutableString string];
[mStringappendFormat:@"%@ xmlns=\"\"",element];
for (NSDictionary*dic in array) {
[mStringappendFormat:@"%@", dic.allKeys.firstObject];
[mStringappendFormat:@"%@", dic.allValues.firstObject];
[mStringappendFormat:@"/%@\t\t", dic.allKeys.firstObject];
}
[mStringappendFormat:@"/%@", element];
return mString;
}
+ ( void )xmlRequestPOSTWithSoapBody:(NSString*)bodyStringandElement:(NSString*)elementsuccess:( void (^)( id responseObject))successfailure:( void (^)(NSError*error))failure {
// DLog(@"....bodyString = %@", bodyString);
NSString*soapStr = [NSString stringWithFormat:
@"?xml version=\"1.0\" encoding=\"utf-8\"?\
soap:Envelope xmlns:xsi=\"\" xmlns:xsd=\"\"\
xmlns:soap=\"\"\
soap:Body%@/soap:Body\
/soap:Envelope",bodyString];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
// 设置请求超时时间
manager.requestSerializer.timeoutInterval = 15;
// 返回NSData
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 设置请求头,也可以不设置
[manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[manager.requestSerializer setValue:[NSString stringWithFormat:@"%zd", soapStr.length] forHTTPHeaderField:@"Content-Length"];
[manager.requestSerializer setValue:[NSString stringWithFormat:@"",element] forHTTPHeaderField:@"SOAPAction"];
// 设置HTTPBody
[manager.requestSerializersetQueryStringSerializationWithBlock:^NSString*(NSURLRequest*request,NSDictionary*parameters,NSError* __autoreleasing *error) {
return soapStr;
}];
[managerPOST:webService_Urlparameters:soapStrprogress:^(NSProgress* _Nonnull uploadProgress) {
}success:^(NSURLSessionDataTask* _Nonnull task, id _Nullable responseObject) {
//DLog(@"responseObject = %@", responseObject);
// 把返回的二进制数据转为字符串
NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
// DLog(@"result = %@", result);
// 利用正则表达式取出之间的字符串
NSString*resultString = [NSStringstringWithFormat:@"(?=%@Result\\).*(?=/%@Result)",element,element];//@"(?=return\\).*(?=/return)"
NSRegularExpression *regular = [[NSRegularExpression alloc] initWithPattern:resultString options:NSRegularExpressionCaseInsensitive error: nil ];
NSDictionary *dict = [NSDictionary dictionary]; for (NSTextCheckingResult*checkingResult in [regularmatchesInString:resultoptions:0range:NSMakeRange(0, result.length)]) {
// 得到字典
dict = [NSJSONSerialization JSONObjectWithData:[[result substringWithRange:checkingResult.range] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error: nil ];
}
if (success) {
success(dict);
}
// DLog(@"dic = %@", dict);
}failure:^(NSURLSessionDataTask* _Nullable task,NSError* _Nonnull error) {
DLog(@"error = %@", error);
if (failure) {
failure(error);
}
}];
}
调用一下:
+ ( void )mallListWithType:(NSString * _Nullable )type
success:( void (^ _Nullable )( id _Nullable responseObject))success
failure:( void (^ _Nullable )(NSString* _Nullable strError))failure {
NSString *element = @"ZHWS_GetActivityMallAdList";
NSArray*bodyArray =@[
@{@"Type":type}
];
NSString*bodyString = [ self convertDicArrayToXML:bodyArrayandElement:element];
[ self xmlRequestPOSTWithSoapBody:bodyStringandElement:elementsuccess:^( id responseObject) {
DLog(@"... 活动相关、商场广告、广告列表 = %@", responseObject);
if (responseObject) {
success(responseObject);
}
}failure:^(NSError*error) {
if (error) {
//failure(error.mj_JSONString);
}
}];
}
近期项目刚好用到这个,之前也没有用过,所以顺手就记录一下。如有错误,看到的小伙伴请指正。
参考链接:
解析xml, 在ios中可以使用NSXMLParser 类来解析。当然也有一些第三方库可以方便操作,如:GDataXml
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流