C 枚举和 XML 之间的转换
在 XML 中存储枚举并再次将其读回的最简洁方法是什么? 假设我有:
enum ETObjectType {ETNormalObjectType, ETRareObjectType, ETEssentialObjectType};
...并且我想要获取一个变量 enum ETObjectType objectType = ETNormalObjectType;
,并将其转换为如下所示的 XML:/对象类型>
。
目前我正在做的是这样的:
NSString* const ETObjectTypeAsString[] = {@"ETNormalObjectType",@"ETRareObjectType",@"ETEssentialObjectType"};
[anXMLElement addChild:[NSXMLElement elementWithName:@"objectType" stringValue:ETObjectTypeAsString[objectType]]];
...但这并不完全理想; 我不高兴每次更改枚举时都更新这两个列表。 但这是可以接受的。 更糟糕的是读回 XML,为此我正在这样做:
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];
}
呸! 这让我很恶心。 至少必须有一种更干净的阅读方式,或者也许有一种统一的读写方式?
我正在使用 Obj-C 和 Cocoa,但我不介意一些纯 C 函数。 如果这是唯一的方法,我什至会使用预处理器。
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};
...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]]];
...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?
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我正在尝试这个解决方案 -
我喜欢它,因为它在编译时检查字符串数组的长度,并且 enumFromStrings 函数是通用且可重用的。 你这样称呼它:
I'm experimenting with this solution -
I like it because it checks the length of the string array at compile time, and the enumFromStrings function is generic and reusable. You call it like so:
我还没有找到比在字符串中复制枚举更好的方法。 然而,我的做法略有不同,即:
那么在实现中:
我使用#define的原因是为了避免在头文件中声明数组,但是将枚举的定义与枚举的定义分开是疯狂的字符串的序列,所以这是我发现的最好的折衷方案。
由于代码是样板代码,因此您实际上可以将它们作为 NSArray 上的类别。
进而:
I haven't found a better way than duplicating the enum in a string. However, I do it slightly differently, namely:
then in the implementation:
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.
Since the code is boilerplate, you can actually make them a category on NSArray.
and then:
我赞同乔恩的解决方案,但您可以使用可怕的 X-macro 来避免重复你自己。 我不知道如何用代码格式评论乔恩的答案,所以这里将其作为一个新答案。
I echo Jon's solution, but you can use the dreaded X-macro to avoid repeating yourself at all. I don't know how to comment on Jon's answer with code formatting, so here it is as a new answer.
XML 的伟大之处在于它几乎可以转换为任何内容,甚至可以转换为代码。 翻译一次只需要(很多)努力。 我参与过多个将 XML 转换为代码的项目。 这节省了很多时间。 例如,“XSLT Cookbook 第 2 版,S. Mangano,O'Reilley”一书的第 12 章介绍了该技术。
这不是一个简单的解决方案,但如果你有一个好的映射
- 有单点定义(您的 xml)
- 可以生成带有枚举的.h文件
- 可以生成表或函数来读取/写入 xml 中的值
这取决于枚举的数量以及它们更改的频率(如果值得)。
祝你好运!
The great thing of XML is that it can transform to nearly anything, even to code. It just takes (a lot of) effort to make the translation once. I have worked in several projects where XML was translated to code. And this saved a lot of time. This technique is for instance, covered in chapter 12 of the book "XSLT Cookbook 2nd edition, S. Mangano, O'Reilley".
It's not an easy solution, but if you have a good mapping you
- have a single point of definition (your xml)
- can generate .h files with enum
- can generate tables or functions to read/write values in xml
It depends on the number of enums and how often they change if it is worthwhile.
Good luck!
以下是我通常编写这些风格的方法的方式:
您最终必须将枚举值放在两个位置:原始枚举和将整数值映射到其字符串名称的数组。 不过,实际执行映射的两个函数没有映射的副本。
Here's how I typically write these styles of methods:
You end up having to put your enumeration values in two places, the original enumeration, and the array that maps integer values to their string names. The two functions that actually do the mapping don't have copies of the maps though.