现在,我已经从Redland RDF库中分离出了一个问题,之前也问过这个问题。所以我仍然在想:是什么导致了下面的测试用例失败?
本质上,应该发生以下情况:我正在构建两个RDF模型,每个模型都包含一个事件ID,我使用这些事件ID作为字典(hashtable)中的键。由于RDF模型是C结构,所以我将它们包装在一个目标C类中,以获得可以存储在字典中的内容。现在,当我试图通过这些不同的键从字典中检索两个RDF模型时,我总是返回相同的RDF模型。RDF模型的指针值是不同的,但所有包含的RDF节点显然都是相同的。我遗漏了什么?(顺便说一句,我很确定问题不在于所有的混淆:)
//
// RedlandRdfStandaloneTests.h
//
#import <SenTestingKit/SenTestingKit.h>
@interface RedlandRdfStandaloneTests : SenTestCase
@end
//
// RedlandRdfStandaloneTests.m
//
#import "librdf.h"
#import "RdfModelWrapper.h"
#import "RedlandRdfStandaloneTests.h"
// namespace URIs
#define OBFUSCATED6_NAMESPACE @"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED7#"
// datatype properties
#define OBFUSCATED6_EVENT_ID_LOCAL_NAME @"eventId"
// individuals
#define OBFUSCATED6_CALENDAR_EVENT_LOCAL_NAME @"CalendarEvent"
#define IDENTIFIER_1 @"dc4bc97ugu7kl5hoh2spmanob4"
#define IDENTIFIER_2 @"cbd3mghbgas8juuh4l88rt04ec"
@interface RedlandRdfStandaloneTests ()
@property (assign, readonly) librdf_world *rdfWorld;
@property (assign, readonly) librdf_storage *rdfStorage;
@property (assign, readonly) librdf_node *rdfTypeProperty;
@property (assign, readonly) librdf_uri *obfuscated8NamespaceUri;
@property (assign, readonly) librdf_node *obfuscated8EventIdProperty;
@property (assign, readonly) librdf_node *obfuscated8CalendarEventIndividual;
@property (assign, readonly) librdf_parser *rdfParser;
@property (assign, readonly) librdf_uri *baseUri;
@property (strong, readonly) NSString *rdfModel1AsString;
@property (strong, readonly) NSString *rdfModel2AsString;
@end
@implementation RedlandRdfStandaloneTests
- (void)test
{
NSMutableDictionary *identifiersToRdfModelWrappers = [NSMutableDictionary dictionary];
librdf_model *rdfModel;
{
rdfModel = librdf_new_model(_rdfWorld, _rdfStorage, NULL);
librdf_parser_parse_string_into_model(_rdfParser, (const unsigned char *)_rdfModel1AsString.UTF8String, _baseUri, rdfModel);
RdfModelWrapper *rdfModelWrapper = [[RdfModelWrapper alloc] initWithRdfModel:rdfModel];
[identifiersToRdfModelWrappers setObject:rdfModelWrapper forKey:IDENTIFIER_1];
[self writeModel:rdfModel withRdfWorld:_rdfWorld]; // #1: ok -- same as _rdfModel1AsString with eventId same as IDENTIFIER_1
}
{
rdfModel = librdf_new_model(_rdfWorld, _rdfStorage, NULL);
librdf_parser_parse_string_into_model(_rdfParser, (const unsigned char *)_rdfModel2AsString.UTF8String, _baseUri, rdfModel);
RdfModelWrapper *rdfModelWrapper = [[RdfModelWrapper alloc] initWithRdfModel:rdfModel];
[identifiersToRdfModelWrappers setObject:rdfModelWrapper forKey:IDENTIFIER_2];
[self writeModel:rdfModel withRdfWorld:_rdfWorld]; // #2: ok -- same as _rdfModel2AsString with eventId same as IDENTIFIER_2
}
{
RdfModelWrapper *rdfModelWrapper = [identifiersToRdfModelWrappers objectForKey:IDENTIFIER_1];
rdfModel = rdfModelWrapper.rdfModel;
librdf_node *eventResource = librdf_model_get_source(rdfModel, _rdfTypeProperty, _obfuscated8CalendarEventIndividual);
librdf_node *eventIdLiteral = librdf_model_get_target(rdfModel, eventResource, _obfuscated8EventIdProperty);
NSString *eventId = [NSString stringWithCString:librdf_node_get_literal_value_as_latin1(eventIdLiteral) encoding:NSISOLatin1StringEncoding];
[self writeModel:rdfModel withRdfWorld:_rdfWorld]; // #3: error -- same as _rdfModel2AsString with eventId same as IDENTIFIER_2
STAssertEqualObjects(IDENTIFIER_1, eventId, nil); // #4: fails
}
{
RdfModelWrapper *rdfModelWrapper = [identifiersToRdfModelWrappers objectForKey:IDENTIFIER_2];
rdfModel = rdfModelWrapper.rdfModel;
librdf_node *eventResource = librdf_model_get_source(rdfModel, _rdfTypeProperty, _obfuscated8CalendarEventIndividual);
librdf_node *eventIdLiteral = librdf_model_get_target(rdfModel, eventResource, _obfuscated8EventIdProperty);
NSString *eventId = [NSString stringWithCString:librdf_node_get_literal_value_as_latin1(eventIdLiteral) encoding:NSISOLatin1StringEncoding];
[self writeModel:rdfModel withRdfWorld:_rdfWorld]; // #5: ok -- same as _rdfModel2AsString with eventId same as IDENTIFIER_2
STAssertEqualObjects(IDENTIFIER_2, eventId, nil); // #6: ok
}
}
- (void)writeModel:(librdf_model *)rdfModel withRdfWorld:(librdf_world *)rdfWorld
{
raptor_world *raptorWorld = librdf_world_get_raptor(rdfWorld);
raptor_iostream *stream = raptor_new_iostream_to_file_handle(raptorWorld, stdout);
NSAssert(stream != nil, @"cannot create stream");
int flag = librdf_model_write(rdfModel, stream);
NSAssert(flag == 0, @"librdf_model_write() failed: %d", flag);
raptor_free_iostream(stream);
}
#pragma mark -
#pragma mark override SenTestCase
- (void)setUp
{
_rdfWorld = librdf_new_world();
librdf_world_open(_rdfWorld);
_rdfStorage = librdf_new_storage(_rdfWorld, "memory", NULL, NULL);
_rdfTypeProperty = LIBRDF_MS_type(_rdfWorld);
_obfuscated8NamespaceUri = librdf_new_uri(_rdfWorld, (const unsigned char *)OBFUSCATED6_NAMESPACE.UTF8String);
_obfuscated8EventIdProperty = librdf_new_node_from_uri_local_name(_rdfWorld, _obfuscated8NamespaceUri, (const unsigned char *)OBFUSCATED6_EVENT_ID_LOCAL_NAME.UTF8String);
_obfuscated8CalendarEventIndividual = librdf_new_node_from_uri_local_name(_rdfWorld, _obfuscated8NamespaceUri, (const unsigned char *)OBFUSCATED6_CALENDAR_EVENT_LOCAL_NAME.UTF8String);
_rdfParser = librdf_new_parser(_rdfWorld, NULL, "application/rdf+xml", NULL);
NSAssert(_rdfParser != nil, @"no RDF parser");
_baseUri = librdf_new_uri(_rdfWorld, (const unsigned char *)"http://www.w3.org/1999/02/22-rdf-syntax-ns#");
_rdfModel1AsString = @"<rdf:RDF \
xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" \
xmlns:j.0=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED7#\" \
xmlns:owl=\"http://www.w3.org/2002/07/owl#\" \
xmlns=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED2#\" \
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\" \
xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" \
xmlns:mo=\"http://purl.org/ontology/mo/\">\
<rdf:Description rdf:about=\"http://www.OBFUSCATED5.com/event/show/2224183\">\
<rdf:type rdf:resource=\"http://www.w3.org/2000/01/rdf-schema#Resource\"/>\
<rdf:type rdf:resource=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED7#CalendarEvent\"/>\
<j.0:eventId>dc4bc97ugu7kl5hoh2spmanob4</j.0:eventId>\
<j.0:hasOrganization rdf:resource=\"http://www.OBFUSCATED1.com/2013/05/MDW#MDW\"/>\
</rdf:Description>\
</rdf:RDF>";
_rdfModel2AsString = @"<rdf:RDF \
xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" \
xmlns:j.0=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED7#\" \
xmlns:owl=\"http://www.w3.org/2002/07/owl#\" \
xmlns=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED2#\" \
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\" \
xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" \
xmlns:mo=\"http://purl.org/ontology/mo/\">\
<rdf:Description rdf:about=\"http://www.OBFUSCATED4.com/veranstaltungen/uebersicht/veranstaltung-details/event/201305221830/OBFUSCATED9/\">\
<rdf:type rdf:resource=\"http://www.w3.org/2000/01/rdf-schema#Resource\"/>\
<rdf:type rdf:resource=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED7#CalendarEvent\"/>\
<j.0:eventId>cbd3mghbgas8juuh4l88rt04ec</j.0:eventId>\
<j.0:hasOrganization rdf:resource=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED3#OBFUSCATED3\"/>\
<j.0:hasLocation rdf:resource=\"http://www.OBFUSCATED1.com/2013/05/OBFUSCATED3#Konzertsaal\"/>\
</rdf:Description>\
</rdf:RDF>";
[super setUp];
}
- (void)tearDown
{
librdf_free_node(_obfuscated8EventIdProperty);
librdf_free_node(_obfuscated8CalendarEventIndividual);
librdf_free_uri(_obfuscated8NamespaceUri);
librdf_free_node(_rdfTypeProperty);
librdf_free_uri(_baseUri);
librdf_free_parser(_rdfParser);
librdf_free_storage(_rdfStorage);
librdf_free_world(_rdfWorld);
[super tearDown];
}
@end
//
// RdfModelWrapper.h
//
#import "librdf.h"
@interface RdfModelWrapper : NSObject
@property (assign, readonly) librdf_model *rdfModel;
- (id)initWithRdfModel:(librdf_model *)rdfModel;
@end
//
// RdfModelWrapper.m
//
#import "RdfModelWrapper.h"
@implementation RdfModelWrapper
- (id)initWithRdfModel:(librdf_model *)rdfModel
{
self = [super init];
if (self) {
_rdfModel = rdfModel; // RDFModelWrapper effectively takes ownership of rdfModel, i.e. is in charge of freeing it
}
return self;
}
- (void)dealloc
{
librdf_free_model(_rdfModel);
}
@end发布于 2013-06-02 20:16:22
图书馆员模型是由一个存储支持的。这两个模型都由相同的memory存储支持,因此包含相同的数据,即使模型实例不同。
您还使用了查询函数librdf_model_get_source()和librdf_model_get_target(),它们只返回第一个匹配项(如果有的话),而不是返回librdf_iterator中所有匹配语句的函数,例如librdf_model_get_sources()、librdf_model_get_targets()或泛型librdf_model_find_statements()。这就是为什么所有查询都返回相同的节点的原因。
因此,如果您想要处理不同的模型,请确保它们的支持库也是不同的。
(我记得dajobe有一些让模型和储藏室分开的理由,但不记得它是什么。)
https://stackoverflow.com/questions/16810319
复制相似问题