Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从NSString中删除html实体-解决方案可在iOS模拟器和设备上运行_Ios_Objective C_Nsstring_Html Entities - Fatal编程技术网

从NSString中删除html实体-解决方案可在iOS模拟器和设备上运行

从NSString中删除html实体-解决方案可在iOS模拟器和设备上运行,ios,objective-c,nsstring,html-entities,Ios,Objective C,Nsstring,Html Entities,我将html存储在NSString中。我从internet下载并使用NSXMLParser解析它。然而,它似乎与诸如ó,&bdquo,等等。这确实是一个很大的问题,因为它告诉我它失败了,并停止进一步的解析 我在stackoverflow的不同主题中找到了一些很好的解决方案,但他们建议使用NSString+HTML类别或Google Toolbox for Mac(NSString类别使用GTM)。我已经有了使用GTM的项目,这使得在iOS模拟器上运行我的应用程序变得不可能,所以我想避

我将html存储在
NSString
中。我从internet下载并使用
NSXMLParser
解析它。然而,它似乎与诸如
ó
&bdquo
等等。这确实是一个很大的问题,因为它告诉我它失败了,并停止进一步的解析


我在stackoverflow的不同主题中找到了一些很好的解决方案,但他们建议使用NSString+HTML类别或Google Toolbox for Mac(NSString类别使用GTM)。我已经有了使用GTM的项目,这使得在iOS模拟器上运行我的应用程序变得不可能,所以我想避免这种情况。

使用
NSScanner
编写自己的方法可能是最简单的。注意,实体语法比替换列表稍微复杂一些;即,您需要支持:

  • &#D;其中D是十进制数
  • &#x*H*;其中H是十六进制数(大写和小写都可以)
然后,您将需要一个命名实体的映射表(有)

下面是一些代码(在堆栈溢出中编写,未经测试),可以帮助您开始:

static NSDictionary *entityDict;

if (!entityDict)
  entityDict = loadEntityMappingTable();

NSScanner *scanner = [NSScanner scannerWithString:myHTMLString];
NSMutableString *result = [NSMutableString string];

[scanner setCharactersToBeSkipped:nil]; // Don’t skip whitespace

while (![scanner isAtEnd]) {
  NSString *chunk, *name;

  if ([scanner scanUpToString:@"&" intoString:chunk])
    [result appendString:chunk];

  if ([scanner scanString:@"#" intoString:NULL]) {
    unsigned uch;
    NSUInteger scanLoc;
    BOOL hex = NO;

    // This is a numeric reference
    if ([scanner scanString:@"x" intoString:NULL]) {
      hex = YES;
      scanLoc = [scanner scanLocation];
      if (![scanner scanHexInt:&uch]) {
        // If we fail, show the entire thing in the result string
        [result appendString:@"&#x"];
        continue;
      }
    } else {
      int ich;
      scanLoc = [scanner scanLocation];
      if (![scanner scanInt:&ich]) {
        // If we fail, show the entire thing
        [result appendString:@"&#"];
        continue;
      }

      if (ich < 0) {
        // Bad Unicode code point
        [result appendString:@"&#"];
        [scanner setScanLocation:scanLoc];
        continue;
      }

      uch = (unsigned)ich;
    }

    // You may also care to prohibit control codes (depending on your application)
    // i.e. uch < 0x20 || uch >= 0x7f && uch < 0xa0

    if (uch >= 0xd800 && uch <= 0xdfff || uch > 0x10ffff) {
      // Bad Unicode code point; show it in the result
      [result appendString:hex ? @"&#x" : @"&#"];
      [scanner setScanLocation:scanLoc];
      continue;
    }

    if (![scanner scanString:@";" intoString:NULL]) {
      // Unterminated; show it in the result
      [result appendString:hex ? @"&#x" : @"&#"];
      [scanner setScanLocation:scanLoc];
      continue;
    }

    if (uch < 0xffff)
      [result appendFormat:@"%C", uch];
    else {
      unichar lo, hi;

      hi = 0xd800 | (uch >> 10);
      lo = 0xdc00 | (uch & 0x3ff);

      [result appendFormat:@"%C%C", hi, lo];
    }

    continue;
  }

  if ([scanner scanUpToString:@";" intoString:&name]) {
    NSString *ch;

    if (![scanner scanString:@";" intoString:NULL]) {
      // Unterminated; show it in the result
      [result appendFormat:@"&%@", name];
      continue;
    }

    ch = [entityDict objectForKey:[name lowercaseString]];

    if (!ch) {
      // Unrecognised; show it in the result
      [result appendFormat:@"&%@;", name];
      continue;
    }

    [result appendString:ch];
  }
}
静态NSDictionary*entityDict;
if(!entityDict)
entityDict=loadEntityMappingTable();
NSScanner*scanner=[NSScanner scannerWithString:myHTMLString];
NSMutableString*结果=[NSMutableString];
[扫描仪设置字符stobeskiped:nil];//不要跳过空白
而(![scanner isattend]){
NSString*chunk,*name;
if([scanner scanuptString:@“&”intoString:chunk])
[结果追加字符串:块];
if([scanner scanString:@“#”intoString:NULL]){
未签名的uch;
NSU整数扫描定位;
布尔十六进制=否;
//这是一个数字参考
if([scanner scanString:@“x”intoString:NULL]){
十六进制=是;
scanLoc=[扫描仪扫描位置];
如果(![scanner scanHexInt:&uch]){
//如果失败,则在结果字符串中显示整个内容
[结果追加字符串:@“&#x”];
继续;
}
}否则{
int ich;
scanLoc=[扫描仪扫描位置];
如果(![扫描仪扫描:&ich]){
//如果我们失败了,展示整个过程
[结果追加字符串:@“&#”];
继续;
}
如果(ich<0){
//错误的Unicode代码点
[结果追加字符串:@“&#”];
[扫描仪设置扫描位置:scanLoc];
继续;
}
uch=(未签名)ich;
}
//您可能还希望禁止控制代码(取决于您的应用)
//即uch<0x20 | | uch>=0x7f&&uch<0xa0
如果(uch>=0xd800&&uch 0x10ffff){
//错误的Unicode代码点;在结果中显示它
[结果追加字符串:十六进制?@“&#x”:@“&#”];
[扫描仪设置扫描位置:scanLoc];
继续;
}
if(![scanner scanString:@”;“intoString:NULL]){
//未终止;在结果中显示
[结果追加字符串:十六进制?@“&#x”:@“&#”];
[扫描仪设置扫描位置:scanLoc];
继续;
}
如果(uch<0xffff)
[结果格式:@“%C”,uch];
否则{
尤尼卡罗,你好,;
hi=0xd800 |(uch>>10);
lo=0xdc00 |(uch&0x3ff);
[结果格式:@“%C%C”,高,低];
}
继续;
}
if([scanner scanuptString:@”;“intoString:&name]){
NSString*ch;
if(![scanner scanString:@”;“intoString:NULL]){
//未终止;在结果中显示
[结果格式:@“&%@”,名称];
继续;
}
ch=[entityDict objectForKey:[name lowercaseString]];
如果(!ch){
//未识别;在结果中显示它
[结果附件格式:@“&%@;”,名称];
继续;
}
[结果追加字符串:ch];
}
}
在函数或方法中的某个地方,实现
loadEntityMappingTable()
初始化映射字典,它应该可以工作


FWIW,同样的通用方法,使用循环和NSScanner,很容易应用于许多类似的问题,而在脚本语言中,这些问题可以通过正则表达式匹配来解决。

到底是什么“使应用程序无法在模拟器上构建”意味着当我在以前的项目中使用GTM时,我无法在模拟器上构建它,但是它在一个设备上工作。问题不清楚,你应该弄清楚你遇到的问题是什么。我编辑了这个问题并澄清了它,希望现在更好。我之前没有注意到ó在我的帖子中显示为ó