KissXML 不返回 xpath 查询的值
Posted
技术标签:
【中文标题】KissXML 不返回 xpath 查询的值【英文标题】:kissXML returning no values for xpath query 【发布时间】:2011-09-06 15:23:18 【问题描述】:我正在尝试使用 KissXML 解析以下 XML 文件(在 iphone 上使用 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>
<tempProfile 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>
使用以下代码从中创建一个核心数据对象:
-(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;
但到目前为止,我尝试的每个 XPath 查询都返回一个长度为 0 的数组。
为了获得名称的值,我尝试了//Person/name
Person/name
//name
name
,它们都返回一个长度为 0 的数组。即使是对/SnowProfile
的查询也会返回一个长度为0 的数组,这让我认为xml 解析出了点问题。我已经验证了 XML 文件,它很好,从 NSlog 输出中我可以看出文件正在加载。
【问题讨论】:
【参考方案1】:定义了一个命名空间xmlns:gml="http://www.opengis.net/gml"
根据我对 xpath 的回忆,您需要在执行 xpath 查询时指定这一点。试试/gml:SnowProfile
看看它是否返回一个长度为 0 的数组以外的东西。然后你就会知道这是否能解决你的问题。
【讨论】:
错误原来是默认命名空间 xmlns="caaml.org/Schemas/V5.0/Profiles/SnowProfileIACS",为了使其正确解析,我必须将文件加载为 mutableString 并在制作之前摆脱命名空间声明将其转换为 DDXmlDocument。【参考方案2】:您必须将 html 标记的“xmlns”属性替换为“noNSxml”才能正确解析。如果你想重用它,它建议你然后 ti put buck xmlns。
【讨论】:
【参考方案3】:可以将默认命名空间重命名并进行查询,而不是将文件作为文本处理并进行修改。详情在this answer,附代码。
【讨论】:
以上是关于KissXML 不返回 xpath 查询的值的主要内容,如果未能解决你的问题,请参考以下文章
XML 解析 - 使用 KissXML 和 XPath 将属性分组到 nsdictionary