kissXML returning no values for xpath query
Im trying to parse the following XML file(generated on iphone with KISSxml) with KissXML :
<?xml version="1.0" encoding="UTF-8"?>
<SnowProfile xmlns="http://caaml.org/Schemas/V5.0/Profiles/SnowProfileIACS" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://caaml.org/Schemas/V5.0/Profiles/SnowProfileIACS http://caaml.org/Schemas/V5.0/Profiles/SnowprofileIACS/CAAMLv5_SnowProfileIACS.xsd" gml:id="2011-09-04-Home">
<metaDataProperty>
<MetaData>
<dateTimeReport>2011-09-04T18:45:10-0700</dateTimeReport>
<srcRef>
<Operation>
<name>My op</name>
<contactPerson>
<Person>
<name>Jesse</name>
</Person>
</contactPerson>
</Operation>
</srcRef>
</MetaData>
</metaDataProperty>
<validTime>
<TimeInstant>
<timePosition>2011-09-04T18:45:10-0700</timePosition>
</TimeInstant>
</validTime>
<snowProfileResultsOf>
<SnowProfileMeasurements dir="top down">
<comment>Testing</comment>
<profileDepth uom="cm">58</profileDepth>
<skyCond>BKN</skyCond>
<precipTI>None</precipTI>
<airTempPres uom="degC">2</airTempPres>
<windSpd uom="ms-1">5</windSpd>
<windDir>
<AspectPosition>
<position>E</position>
</AspectPosition>
</windDir>
<hS>
<Components>
<snowHeight uom="cm">3</snowHeight>
</Components>
</hS>
<penetrationSki uom="cm">14</penetrationSki>
<penetrationFoot uom="cm">8</penetrationFoot>
<penetrationRam uom="cm">22</penetrationRam>
<stratProfile>
<Layer>
<depthTop uom="cm">0</depthTop>
<thickness uom="cm">27</thickness>
<grainFormPrimary>PPsd</grainFormPrimary>
<grainSize uom="mm">14</grainSize>
<hardness uom="">4F</hardness>
<lwc uom="">W</lwc>
<density uom="kg/m3">310</density>
<validFormationTime>
<timeInstant>
<timePosition>2011-09-05</timePosition>
</timeInstant>
</validFormationTime>
</Layer>
<Layer>
<depthTop uom="cm">27</depthTop>
<thickness uom="cm">31</thickness>
<grainFormPrimary>PPnd</grainFormPrimary>
<grainFormSecondary>PPpl</grainFormSecondary>
<grainSize uom="mm">11</grainSize>
<hardness uom="">1F</hardness>
<lwc uom="">S</lwc>
<density uom="kg/m3">263</density>
<validFormationTime>
<timeInstant>
<timePosition>2011-07-05</timePosition>
</timeInstant>
</validFormationTime>
</Layer>
</stratProfile>
<temp开发者_如何学JAVAProfile uomDepth="cm" uomTemp="C">
<Obs>
<depth>2</depth>
<snowTemp>0</snowTemp>
</Obs>
<Obs>
<depth>18</depth>
<snowTemp>-4</snowTemp>
</Obs>
<Obs>
<depth>52</depth>
<snowTemp>-1</snowTemp>
</Obs>
</tempProfile>
<stbTests>
<RBlockTest>
<comment>Test</comment>
<failedOn>
<Layer uom="cm">
<depthTop>25</depthTop>
</Layer>
<Results>
<testScore>3</testScore>
<fractureCharacter>Q3</fractureCharacter>
</Results>
</failedOn>
</RBlockTest>
</stbTests>
</SnowProfileMeasurements>
</snowProfileResultsOf>
<locRef>
<ObsPoint>
<name>Home</name>
<validElevation>
<ElevationPosition uom="m">
<position>110</position>
</ElevationPosition>
</validElevation>
<validAspect>
<AspectPosition>
<position>SW</position>
</AspectPosition>
</validAspect>
<validSlopeAngle>
<SlopeAnglePosition uom="deg">
<position>2</position>
</SlopeAnglePosition>
</validSlopeAngle>
<pointLocation>
<gml:Point srsDimension="2">
<gml:pos></gml:pos>
</gml:Point>
</pointLocation>
</ObsPoint>
</locRef>
</SnowProfile>
Using the following code to create a core data object from it:
-(BOOL)importFile:(NSString *)fileName error:(NSError **)error{
NSData *data = [[NSData alloc] initWithContentsOfFile:fileName];
if(data == nil)
return NO;
DDXMLDocument *doc = [[DDXMLDocument alloc] initWithData:data options:0 error:error];
//if(error != nil)
if(doc == nil)
return NO;
snowPit *pit = [snowPit pitForCAAMLProfile:doc];
if(pit != nil)
return YES;
else
return NO;
}
+(snowPit *)pitForCAAMLProfile:(DDXMLDocument *)xmlDoc{
NSLog(@"%@", [xmlDoc XMLStringWithOptions:DDXMLNodePrettyPrint] );
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSError *err;
snowPit *newPit = [[pitManager sharedManager] newPitWithoutDefaults];
NSArray *fields = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"CAAMLImportFields" ofType:@"plist"]];
for(NSDictionary *importField in fields){
NSString *field = [importField valueForKey:@"field"];
NSString *xpath = [importField valueForKey:@"xpath"];
NSString *attribute = [importField valueForKey:@"attribute"];
NSArray *nodes;
if(xpath != nil && [xpath length] > 0){
nodes = [xmlDoc nodesForXPath:xpath error:nil];
NSLog(@"Field:%@, xpath:%@, attribute:%@ nodes:%i", field, xpath, attribute, [nodes count]);
if(nodes != nil && [nodes count] > 0){
NSString *value;
if(attribute != nil && [attribute length] > 0){
DDXMLNode *attNode = [[nodes objectAtIndex:0] attributeForName:attribute];
if(attNode != nil)
value = [attNode stringValue];
}else
value = [[nodes objectAtIndex:0] stringValue];
if(value != nil && [value length] > 0)
[newPit setValue:value forKey:field];
}
}
}
[dateFormatter release];
return newPit;
}
But so far every XPath query I try returns an array of 0 length.
To get the value for name i have tried //Person/name
Person/name
//name
name
And they all return a 0 length array. Even a query for /SnowProfile
returns a 0 length array which leads me to think that something is going wrong with the xml parsing. I have validated the XML file and it is fine, and from the NSlog output I can tell that the file is being loaded.
There is a namespace defined xmlns:gml="http://www.opengis.net/gml"
From my recollection of xpath, you need to specify that when you do an xpath query. Try /gml:SnowProfile
to see if that returns something other than a 0 length array. You will then know if this will solve your problem.
You have to replace the "xmlns" attribute of the html tag by "noNSxml" to have a correct parsing. If you want to reuse it, it suggest you then ti put buck xmlns.
Rather than processing the file as text and modifying it, the default namespace can be renamed and thus queried. Details are in this answer, with code.
精彩评论