多个Redland RDF模型似乎包含与最后解析的模型相同的RDF节点



我现在已经隔离了Redland RDF库的一个问题,我之前也问过这个问题。所以我仍然在想:是什么导致下面的测试用例失败?

实际上应该发生的事情如下:我正在构建两个RDF模型,每个模型都包含一个事件ID。我使用这些事件id作为字典(哈希表)的键。由于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

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有一些理由保持模型和存储分开,但不记得是什么)

相关内容

  • 没有找到相关文章

最新更新