在 NSString 中查找数字节点并在其前面添加下划线以修复无效的 XML
我有一个返回给我的 XML
字符串,有时使用数字作为节点名称是无效的,例如:<2>
。我想扫描保存 XML 的整个 NSString
,并搜索以下内容:
<numeric value // e.g. <1 or <2
</numeric value // e.g. </1 or </2
然后我想在数字前放置一个下划线,以便它将无效的更改为有效的 XML
,如下所示:
<_2>
</_2>
我想知道 NSScanner
是否可以完成这项工作,但我不确定如何解决这个问题。现在我只是使用 stringByReplacingOccurrencesOfString:withString: ,但我必须在要替换的数值中进行硬编码,我认为这不是一个好主意。
更新:
我尝试了一下并使用了 NSRange。这是我想出的。它的工作效率约为 95%,但在大型 xml 字符串上它会丢失最后几个 标记,不知道为什么。对于改进这个问题有什么意见或帮助吗?
// Changeable string
NSMutableString *editable = [[[NSMutableString alloc] initWithString:str] autorelease];
// Number Formatter
NSLocale *l_en = [[[NSLocale alloc] initWithLocaleIdentifier: @"en_US"] autorelease];
NSNumberFormatter *f = [[[NSNumberFormatter alloc] init] autorelease];
[f setLocale: l_en];
// Make our first loop
NSUInteger count = 0, length = [str length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound) {
// Find first character
range = [str rangeOfString: @"<" options:0 range:range];
// Make sure we have not gone too far
if (range.location+1 <= length) {
// Check the digit after this
NSString *after = [NSString stringWithFormat:@"%c", [str characterAtIndex:range.location+1]];
// Check if we return the number or not
if ([f numberFromString:after]) {
// Update the string
[editable insertString:@"_" atIndex:(range.location+1)+count];
count++;
}//end
}//end
// Check our range
if(range.location != NSNotFound) {
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
}//end
}//end
// Our second part
NSUInteger slashLength = [editable length];
NSRange slashRange = NSMakeRange(0, slashLength);
while(slashRange.location != NSNotFound) {
// Find first character
slashRange = [editable rangeOfString: @"</" options:0 range:slashRange];
// Make sure we have not gone too far
if (slashRange.location+2 <= slashLength) {
// Check the digit after this
NSString *afterSlash = [NSString stringWithFormat:@"%c", [editable characterAtIndex:slashRange.location+2]];
// Check if we return the number or not
if ([f numberFromString:afterSlash]) {
// Update the string
[editable insertString:@"_" atIndex:(slashRange.location+2)];
}//end
}//end
// Check our range
if(slashRange.location != NSNotFound) {
slashRange = NSMakeRange(slashRange.location + slashRange.length, slashLength - ((slashRange.location+2) + slashRange.length));
}//end
}//end
NSLog(@"%@", editable);
I have an XML
string that gets returned to me, sometimes it is invalid using numbers as node names such as: <2>
. I would like to scan my entire NSString
which holds the XML, and search for the following:
<numeric value // e.g. <1 or <2
</numeric value // e.g. </1 or </2
I would then like to place an underscore before the number, so that it will change the invalid, to valid XML
, like the following:
<_2>
</_2>
I am wondering is NSScanner
would do the job, but I am unsure how to attack this problem. Right now I am just using stringByReplacingOccurrencesOfString:withString:
but I am having to hardcode in the number values to replace, which I don't think is a good idea.
UPDATE:
I gave it a try and used NSRange. Here is what I came up with. It is working about 95%, but on large xml strings it misses the last few </ >
tags, not sure why. Any comments or help on improving this?
// Changeable string
NSMutableString *editable = [[[NSMutableString alloc] initWithString:str] autorelease];
// Number Formatter
NSLocale *l_en = [[[NSLocale alloc] initWithLocaleIdentifier: @"en_US"] autorelease];
NSNumberFormatter *f = [[[NSNumberFormatter alloc] init] autorelease];
[f setLocale: l_en];
// Make our first loop
NSUInteger count = 0, length = [str length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound) {
// Find first character
range = [str rangeOfString: @"<" options:0 range:range];
// Make sure we have not gone too far
if (range.location+1 <= length) {
// Check the digit after this
NSString *after = [NSString stringWithFormat:@"%c", [str characterAtIndex:range.location+1]];
// Check if we return the number or not
if ([f numberFromString:after]) {
// Update the string
[editable insertString:@"_" atIndex:(range.location+1)+count];
count++;
}//end
}//end
// Check our range
if(range.location != NSNotFound) {
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
}//end
}//end
// Our second part
NSUInteger slashLength = [editable length];
NSRange slashRange = NSMakeRange(0, slashLength);
while(slashRange.location != NSNotFound) {
// Find first character
slashRange = [editable rangeOfString: @"</" options:0 range:slashRange];
// Make sure we have not gone too far
if (slashRange.location+2 <= slashLength) {
// Check the digit after this
NSString *afterSlash = [NSString stringWithFormat:@"%c", [editable characterAtIndex:slashRange.location+2]];
// Check if we return the number or not
if ([f numberFromString:afterSlash]) {
// Update the string
[editable insertString:@"_" atIndex:(slashRange.location+2)];
}//end
}//end
// Check our range
if(slashRange.location != NSNotFound) {
slashRange = NSMakeRange(slashRange.location + slashRange.length, slashLength - ((slashRange.location+2) + slashRange.length));
}//end
}//end
NSLog(@"%@", editable);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我最终找到了一个解决方案。这是我使用的方法:
因此,您可以使用以下方法进行测试:
I ended up figuring out a solution. Here is the method that I used:
So, then you could test it using: