ç枚举和XML之间的转换 [英] Converting between C enum and XML

查看:194
本文介绍了ç枚举和XML之间的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是存储在XML枚举和阅读一遍回退干净的方式?说我有:

What's the cleanest way to store an enum in XML and read it back out again? Say I've got:

enum ETObjectType {ETNormalObjectType, ETRareObjectType, ETEssentialObjectType};

...我想拿一个变量,枚举ETObjectType的objectType = ETNormalObjectType; ,并将其转换为XML,看起来像这样: <&的objectType GT; ETNormalObjectType< /的objectType方式>

...and I want to take a variable, enum ETObjectType objectType = ETNormalObjectType;, and convert it to XML that looks like this: <objectType>ETNormalObjectType</objectType>.

目前我在做什么是这样的:

Currently what I'm doing is something like this:

NSString* const ETObjectTypeAsString[] = {@"ETNormalObjectType",@"ETRareObjectType",@"ETEssentialObjectType"};

[anXMLElement addChild:[NSXMLElement elementWithName:@"objectType" stringValue:ETObjectTypeAsString[objectType]]];

...但是,这并不完全理想;我不开心大约每更改我的枚举时间更新这两个列表。但它是可以接受的。多,更糟糕的是多少读取XML回来,我目前做这行其中:

...but that's not entirely ideal; I'm not happy about updating both lists every time I change my enum. But it's acceptable. Much, much worse is reading XML back in, for which I am currently doing this:

if ([[[anXMLElement childNamed:@"objectType"] stringValue] isEqualToString:@"ETRareObjectType"])
{
    [self initObjectType:ETRareObjectType];
}
else if ([[[anXMLElement childNamed:@"objectType"] stringValue] isEqualToString:@"ETEssentialObjectType"])
{
    [self initObjectType:ETEssentialObjectType];
}
else
{
    [self initObjectType:ETNormalObjectType];
}

呸!这令我作呕。这里一定是读一个更清洁的方式,至少,或者读写一种统一的方式?

Yuck! This disgusts me. There's got to be a cleaner way to read, at least, or perhaps a unified way to read and write?

我使用的OBJ-C和Cocoa,但我不会介意一些纯粹的C函数。我甚至会使用preprocessor的东西,如果它是唯一的方法。

I'm using Obj-C and Cocoa, but I wouldn't mind some pure C functions. I'd even use preprocessor stuff, if it's the only way.

推荐答案

我还没有发现比在一个字符串复制枚举更好的办法。但是,我这样做略有不同,分别是:

I haven't found a better way than duplicating the enum in a string. However, I do it slightly differently, namely:

typedef enum {
    kManipulateWindowTargetFrontWindow,
    kManipulateWindowTargetNamedWindow, 
    kManipulateWindowTargetWindowNameContaining, 
    kManipulateWindowTargetDEFAULT = kManipulateWindowTargetFrontWindow, 
} ManipulateWindowTargetType;
#define kManipulateWindowTargetTypeNamesArray @"FrontWindow", @"NamedWindow", @"WindowNameContaining", nil

然后在执行

static NSArray* kManipulateWindowTargetTypeArray = [[NSArray alloc] initWithObjects: kManipulateWindowTargetTypeNamesArray];

NSString* ManipulateWindowTargetTypeToString( ManipulateWindowTargetType mwtt )
{
    return [kManipulateWindowTargetTypeArray objectAtIndex:mwtt];
}

ManipulateWindowTargetType ManipulateWindowTargetTypeFromString( NSString* s )
{
    NSUInteger n = [kManipulateWindowTargetTypeArray indexOfObject:s];
    check( n != NSNotFound );
    if ( n == NSNotFound ) {
        n = kManipulateWindowTargetDEFAULT;
    }
    return (ManipulateWindowTargetType) n;
}

我之所以使用#定义是避免声明在头文件中的数组,但它会很疯狂,从字符串的顺序定义枚举的定义分开,所以这是我最好的折衷办法已经找到。

The reason I use the #define is to avoid declaring the array in the header file, but it would be insane to separate the definition of the enum from the definition of the sequence of strings, so this is the best compromise I've found.

由于code为样板,你其实可以让他们的NSArray一个类别。

Since the code is boilerplate, you can actually make them a category on NSArray.

@interface NSArray (XMLExtensions)

- (NSString*) stringWithEnum: (NSUInteger) e;
- (NSUInteger) enumFromString: (NSString*) s default: (NSUInteger) def;
- (NSUInteger) enumFromString: (NSString*) s;

@end

@implementation NSArray (XMLExtensions)

- (NSString*) stringWithEnum: (NSUInteger) e;
{
    return [self objectAtIndex:e];
}

- (NSUInteger) enumFromString: (NSString*) s default: (NSUInteger) def;
{
    NSUInteger n = [self indexOfObject:s];
    check( n != NSNotFound );
    if ( n == NSNotFound ) {
        n = def;
    }
    return n;
}

- (NSUInteger) enumFromString: (NSString*) s;
{
    return [self enumFromString:s default:0];
}


@end

和则:

NSLog( @"s is %@", [kManipulateWindowTargetTypeArray stringWithEnum:kManipulateWindowTargetNamedWindow] );
ManipulateWindowTargetType mwtt = (ManipulateWindowTargetType)[kManipulateWindowTargetTypeArray enumFromString:@"WindowNameContaining" default:kManipulateWindowTargetDEFAULT];
NSLog( @"e is %d", mwtt );

这篇关于ç枚举和XML之间的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆