【问题标题】:Objective C - Parsing xml with namespaces using pathObjective C - 使用路径解析带有命名空间的 xml
【发布时间】:2012-04-04 17:10:07
【问题描述】:

我在解析以下 xml 数据时遇到了一些问题:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<encryption xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<resource xmlns="http://ns.nuts-for-africa.com/epubdrm">urn:uuid:7297037a-6a5e-4bb1-bfa3-9a683288adb5</resource>
</KeyInfo>
<CipherData>
<CipherReference URI="OPS/epubbooksinfo.html"/>
</CipherData>
</EncryptedData>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<resource xmlns="http://ns.nuts-for-africa.com/epubdrm">urn:uuid:7297037a-6a5e-4bb1-bfa3-9a683288adb5</resource>
</KeyInfo>
<CipherData>
<CipherReference URI="OPS/chapter-008.html"/>
</CipherData>
</EncryptedData>

我正在使用以下代码读取 xml 文件并对其进行解析。我已经尝试了所有我能想到的 xpath 组合,但无法让它发挥作用:

NSData *encryptData = [self getResourceFileName:filename extension:fileext readFileInZip:@"encryption.xml"]; //this is a function to retrieve files from a zip file. This  is working
if(encryptData != nil){
    //http://www.w3.org/2001/04/xmlenc#
    CXMLDocument* cryptFile = [[CXMLDocument alloc] initWithData:encryptData options:0 error:nil];
    NSArray *encryptionItems = [cryptFile nodesForXPath:@"EncryptedData" namespaceMappings:[NSDictionary dictionaryWithObject:@"http://www.w3.org/2001/04/xmlenc#" forKey:@""] error:nil];
    for (CXMLElement* encEl in encryptionItems) {
        NSArray *uuidArray = [encEl nodesForXPath:@"KeyInfo/resource" namespaceMappings:nil error:nil];
        NSString *uuid = [[uuidArray objectAtIndex:0] stringValue];

        NSArray *fileArray = [encEl nodesForXPath:@"CipherData/CipherReference" namespaceMappings:nil error:nil];
        NSString *fileRef = [[fileArray objectAtIndex:0] stringValue];

        NSLog(@"File: %@ - UUID: %@",fileRef,uuid);

    }

} 

【问题讨论】:

    标签: objective-c xml xpath namespaces


    【解决方案1】:

    我正在使用 CXMLDocuments 和 CXMLElements 并且刚刚花了一些时间处理类似的问题(Google 的 KML 文件)。您的问题可能是由于命名空间问题。当您设置命名空间映射时,给命名空间一个键,然后在您的 XPath 表达式中为您的选择器添加前缀,该键后跟一个冒号 (:)。从一个简单的例子开始,假设你的 XML 是:

    <books xmlns="http://what.com/ever">
      <book>
        <title>Life of Pi</title>
      </book>
      <book>
        <title>Crime and Punishment</book>
      </book
    </books>
    

    你会选择所有的书:

    // So, assuming you've already got the data for the XML document
    CXMLDocument* xmldoc = [[CXMLDocument alloc] initWithData:xmlDocData options:0 error:nil];
    NSDictionary *namespaceMappings = [NSDictionary dictionaryWithObjectsAndKeys:@"http://what.com/ever", @"nskey", nil];
    NSError *error = nil;
    NSArray *bookElements = [xmldoc nodesForXPath:@"/nskey:books/nskey:book" namespaceMappings:mappings error:&error];
    

    请注意,您需要为每个元素添加前缀,而不仅仅是声明命名空间的那个。您正在处理的 XML 文档是一个相当重的命名空间,祝您好运。

    【讨论】:

      【解决方案2】:

      这是一个非常容易使用的 XML 解析器。

      http://www.tbxml.co.uk/TBXML/TBXML_Free.html

      【讨论】:

      • 非常抱歉,但我有义务使用路径和 CXMLDocuments 和 CXMLElements
      猜你喜欢
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 2012-10-14
      • 2013-02-01
      • 2012-06-09
      • 2010-09-12
      • 2014-07-28
      相关资源
      最近更新 更多