2013-05-29 3 views
1

Теперь у меня возникла проблема с Redland RDF libraries, о которой я также спросил previously. Поэтому мне все еще интересно: что может привести к тому, что следующий тестовый сценарий завершится неудачей?Несколько RDF-моделей Redland, похоже, содержат те же узлы RDF из модели, которая была проанализирована последней

По существу, должно произойти следующее: Я строю две модели RDF, каждая из которых содержит идентификатор события. Я использую эти идентификаторы событий как ключи в словаре (хэш-таблицу). Поскольку модели RDF являются структурами C, я обертываю их внутри класса Objective 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 
+0

Просто говоря, я создал Objective-C обертку Redland, продолжая работу Рене Puls: https://github.com/p2/Redland-ObjC – Pascal

+0

@Pascal привет, я только что загрузил этот git и попытался запустить, но получить сообщение об ошибке «configure: error: C компилятор не может создать исполняемый файл» Любая идея? – Ryuk

ответ

1

модели librdf опираются на хранение. Обе модели поддерживаются одним и тем же хранилищем memory и поэтому содержат одни и те же данные, даже если экземпляры модели различны.

Вы также с помощью функции запроса librdf_model_get_source() и librdf_model_get_target(), которые просто возвращают первый матч, если таковые имеются, не функции, которые возвращают все соответствующие заявления в librdf_iterator, такие как librdf_model_get_sources(), librdf_model_get_targets() или родовое librdf_model_find_statements(). Вот почему вы получаете одни и те же узлы для всех запросов.

Итак, если вы хотите работать на разных моделях, убедитесь, что их резервные хранилища также отличаются.

(я помню dajobe имел некоторые рассуждения для хранения моделей и хранилищ отдельных, но не помнит, что это было.)

+0

Thx, вот и все. Я буду следить за временем жизни librdf_models и librdf_storages (и у меня будет обтекание RdfModelWrapper обоим. В случае, если @dajobe прослушивает, мне все равно будет интересно услышать от него, как о воспринимаемых преимуществах этого конкретного вид ассоциации между моделью и ее хранением. – Drux

Смежные вопросы