├── .gitignore ├── AttributeTests.m ├── EncodingTests.m ├── Library-Prefix.pch ├── License.txt ├── README.md ├── RaptureXML.podspec ├── RaptureXML.xcodeproj └── project.pbxproj ├── RaptureXML ├── RXMLElement.h └── RXMLElement.m ├── Tests ├── BoundaryTests.m ├── CopyTests.m ├── DeepChildrenTests.m ├── DeepTests.m ├── ErrorTests.m ├── HTMLTests.m ├── SimpleTests.m ├── Tests-Prefix.pch ├── TextConversionTests.m ├── WildcardTests.m ├── XPathTests.m └── players.xml └── icon.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside -------------------------------------------------------------------------------- /AttributeTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // AttributeTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface AttributeTests : SenTestCase { 12 | NSString *attributedXML_; 13 | } 14 | 15 | @end 16 | 17 | @implementation AttributeTests 18 | 19 | - (void)setUp { 20 | attributedXML_ = @"\ 21 | \ 22 | \ 23 | \ 24 | \ 25 | "; 26 | } 27 | 28 | - (void)testAttributedText { 29 | RXMLElement *rxml = [RXMLElement elementFromXMLString:attributedXML_ encoding:NSUTF8StringEncoding]; 30 | NSArray *atts = [rxml attributeNames]; 31 | STAssertEquals(atts.count, 2U, nil); 32 | STAssertTrue([atts containsObject:@"count"], nil); 33 | STAssertTrue([atts containsObject:@"style"], nil); 34 | 35 | RXMLElement *squarexml = [rxml child:@"square"]; 36 | atts = [squarexml attributeNames]; 37 | STAssertEquals(atts.count, 3U, nil); 38 | STAssertTrue([atts containsObject:@"name"], nil); 39 | STAssertTrue([atts containsObject:@"id"], nil); 40 | STAssertTrue([atts containsObject:@"sideLength"], nil); 41 | } 42 | 43 | @end 44 | 45 | -------------------------------------------------------------------------------- /EncodingTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // EncodingTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 3/31/12. 6 | // Copyright (c) 2012 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface EncodingTests : SenTestCase { 12 | NSString *chineseXML_; 13 | } 14 | 15 | @end 16 | 17 | 18 | 19 | @implementation EncodingTests 20 | 21 | - (void)setUp { 22 | chineseXML_ = @""; 23 | } 24 | 25 | - (void)testChinese { 26 | RXMLElement *rxml = [RXMLElement elementFromXMLString:chineseXML_ encoding:NSUTF8StringEncoding]; 27 | STAssertEqualObjects([rxml attribute:@"data"], @"以晴为主", nil); 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Library-Prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #import 4 | #endif 5 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 John Blanco 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RaptureXML is a simple, block-based XML library for the iOS platform that provides an expressive API that makes XML processing freakin' fun for once in my life. 2 | 3 | # Why do we need *another* XML library? # 4 | 5 | You tell me. Processing XML in Objective-C is an awful, frustrating experience and the resulting code is never readable. I'm tired of it! RaptureXML solves this by providing a *powerful* new interface on top of libxml2. Imagine for a minute the code you'd write to process the XML for a list of baseball team members, retrieving their numbers, names, and positions using your favorite XML processing library. Now, take a look at how you do it with RaptureXML: 6 | 7 | RXMLElement *rootXML = [RXMLElement elementFromXMLFile:@"players.xml"]; 8 | 9 | [rootXML iterate:@"players.player" usingBlock: ^(RXMLElement *e) { 10 | NSLog(@"Player #%@: %@", [e attribute:@"number"], [e child:@"name"].text); 11 | }]; 12 | 13 | RaptureXML changes the game when it comes to XML processing in Objective-C. As you can see from the code, it takes only seconds to understand what this code does. There are no wasted arrays and verbose looping you have to do. The code is a breeze to read and maintain. 14 | 15 | I don't think any more needs to be said. 16 | 17 | # Adding RaptureXML to Your Project # 18 | 19 | The recommended way to add RaptureXML to your project is through CocoaPods. Simply add 'RaptureXML' into your Podfile. 20 | 21 | To install manually, there's just a few simple steps: 22 | 23 | * Copy the RaptureXML/RaptureXML folder into your own project and import "RXMLElement.h" somewhere (e.g., your PCH file). 24 | * Link in libz.dylib to your target. 25 | * Link in libxml2.dylib to your target. 26 | * In your build settings, for the key "Header Search Paths", add "$(SDK_DIR)"/usr/include/libxml2 27 | 28 | RaptureXML supports ARC. You are free to use any version of LLVM or gcc as well! (Though you should be using LLVM by now.) 29 | 30 | # ARC isn't just supported, it's required! 31 | 32 | RaptureXML supports ARC. In fact, it only supports ARC. If you're still running a project that doesn't use ARC, RaptureXML won't be your cup of tea. 33 | 34 | # Getting Started # 35 | 36 | RaptureXML processes XML in two steps: load and path. This means that you first load the XML from any source you want such as file, data, or string. Then, you simply use its query language to find what you need. 37 | 38 | You can load the XML with any of the following constructors: 39 | 40 | RXMLElement *rootXML = [RXMLElement elementFromXMLString:@"...my xml..." encoding:NSUTF8StringEncoding]; 41 | RXMLElement *rootXML = [RXMLElement elementFromXMLFile:@"myfile.xml"]; 42 | RXMLElement *rootXML = [RXMLElement elementFromXMLFilename:@"myfile" elementFromXMLFilename:@"xml"]; 43 | RXMLElement *rootXML = [RXMLElement elementFromXMLData:myData]; 44 | 45 | These constructors return an RXMLElement object that represents the top-level tags. Now, you can query the data in any number of ways. 46 | 47 | Let's pretend your XML looks like this: 48 | 49 | 50 | 51 | 52 | Terry Collins 53 | 1 54 | 55 | 56 | 57 | Jose Reyes 58 | SS 59 | 60 | 61 | 62 | Angel Pagan 63 | CF 64 | 65 | 66 | 67 | David Wright 68 | 3B 69 | 70 | 71 | ... 72 | 73 | 74 | 75 | 76 | First, we'd load the XML: 77 | 78 | RXMLElement *rootXML = [RXMLElement elementFromXMLFile:@"players.xml"]; 79 | 80 | We can immediately query the top-level tag name: 81 | 82 | rootXML.tag --> @"team" 83 | 84 | We can read attributes with: 85 | 86 | [rootXML attribute:@"year"] --> @"2011" 87 | [rootXML attribute:@"name"] --> @"New York Mets" 88 | 89 | We can get the players tag with: 90 | 91 | RXMLElement *rxmlPlayers = [rootXML child:@"players"]; 92 | 93 | If we like, we can get all the individual player tags with: 94 | 95 | NSArray *rxmlIndividualPlayers = [rxmlPlayers children:@"player"]; 96 | 97 | From there, we can process the individual players and be happy. Now, this is already much better than any other XML library we've seen, but RaptureXML can use query paths to make this ridiculously easy. Let's use query paths to improve the conciseness our code: 98 | 99 | [rootXML iterate:@"players.player" usingBlock: ^(RXMLElement *player) { 100 | NSLog(@"Player: %@ (#%@)", [player child:@"name"].text, [player attribute:@"number"]); 101 | }]; 102 | 103 | Your block is passed an RXMLElement representing each player in just one line! Alternatively, you could have shortened it with: 104 | 105 | [rootXML iterate:@"players.player" usingBlock: ^(RXMLElement *player) { 106 | NSLog(@"Player: %@ (#%@)", [player child:@"name"], [player attribute:@"number"]); 107 | }]; 108 | 109 | This also works because RXMLElement#description returns the text of the tag. Query paths are even more powerful with wildcards. Let's say we wanted the name of every person on the team, player or coach. We use the wildcard to get it: 110 | 111 | [rootXML iterate:@"players.*.name" usingBlock: ^(RXMLElement *name) { 112 | NSLog(@"Name: %@", name.text); 113 | }]; 114 | 115 | The wildcard processes every tag rather than the one you would've named. You can also use the wildcard to iterate all the children of an element: 116 | 117 | [rootXML iterate:@"players.coach.*" usingBlock: ^(RXMLElement *e) { 118 | NSLog(@"Tag: %@, Text: %@", e.tag, e.text); 119 | }]; 120 | 121 | This gives us all the tags for the coach. Easy enough? 122 | 123 | # XPath # 124 | 125 | If you don't want to use the custom RaptureXML iteration query syntax, you can use the standard XPath query language as well. Here's how you query all players with XPath: 126 | 127 | [rootXML iterateWithRootXPath:@"//player" usingBlock: ^(RXMLElement *player) { 128 | NSLog(@"Player: %@ (#%@)", [player child:@"name"], [player attribute:@"number"]); 129 | }]; 130 | 131 | And remember, you can also test attributes using XPath as well. Here's how you can find the player with #5: 132 | 133 | [rootXML iterateWithRootXPath:@"//player[@number='5']" usingBlock: ^(RXMLElement *player) { 134 | NSLog(@"Player #5: %@", [player child:@"name"]); 135 | }]; 136 | 137 | Note that you can only use XPath from the document root and it won't matter what RXMLElement you have. If you have a derived RXMLElement, you can still build from the document root. If you're not familiar with XPath, you can use this [handy guide](http://www.w3schools.com/xpath/xpath_syntax.asp). 138 | 139 | # Namespaces # 140 | 141 | Namespaces are supported for most methods, however not for iterations. If you want to use namespaces for that kind of thing, use the -children method manually. When specifying namespaces, be sure to specify the namespace URI and *not* the prefix. For example, if your XML looked like: 142 | 143 | 144 | ... 145 | 146 | 147 | You would access the attributes with: 148 | 149 | NSLog(@"Team Name: %@", [e attribute:@"name" inNamespace:@"*"]); 150 | 151 | # RubyMotion Support # 152 | 153 | RaptureXML is easily integrated into RubyMotion! [Here's how.](http://raptureinvenice.com/797/) 154 | 155 | # Unit Tests as Documentation # 156 | 157 | You can see the full usage of RaptureXML by reading the unit tests in the project. Not only does it show you all the code, but you'll know it works! (You can run the unit tests by pressing Command-U in Xcode) 158 | 159 | # Who Created RaptureXML? # 160 | 161 | RaptureXML was created by John Blanco of Rapture In Venice because he got sick of using all of the bizarre XML solutions for iPhone development. If you like this code and/or need an iOS consultant, get in touch with me via my website, [Rapture In Venice](http://raptureinvenice.com). 162 | -------------------------------------------------------------------------------- /RaptureXML.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'RaptureXML' 3 | s.version = '1.0.1' 4 | s.license = 'MIT' 5 | s.summary = 'A simple, sensible, block-based XML API for iOS and Mac development.' 6 | s.homepage = 'https://github.com/ZaBlanc/RaptureXML' 7 | s.author = { 'John Blanco' => 'zablanc@gmail.com' } 8 | s.source = { :git => 'https://github.com/ZaBlanc/RaptureXML.git', :tag => s.version.to_s } 9 | s.platform = :ios 10 | s.source_files = 'RaptureXML/*' 11 | 12 | s.libraries = 'z', 'xml2' 13 | s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' } 14 | s.requires_arc = true 15 | end -------------------------------------------------------------------------------- /RaptureXML.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 6BD1BD9D1558B7FA00F1D055 /* RaptureXMLFramework */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = 6BD1BD9E1558B7FA00F1D055 /* Build configuration list for PBXAggregateTarget "RaptureXMLFramework" */; 13 | buildPhases = ( 14 | 6BD1BDA61558B82400F1D055 /* Build static lib */, 15 | 6BD1BDA71558B85A00F1D055 /* Assemble Framework */, 16 | 6BD1BDA81558B90300F1D055 /* Copy Headers */, 17 | ); 18 | dependencies = ( 19 | ); 20 | name = RaptureXMLFramework; 21 | productName = RaptureXMLKit; 22 | }; 23 | /* End PBXAggregateTarget section */ 24 | 25 | /* Begin PBXBuildFile section */ 26 | 02041DB81526A71200D1F36A /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 02041DB71526A71200D1F36A /* libxml2.dylib */; }; 27 | 02041DBA1526B0DE00D1F36A /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 02041DB71526A71200D1F36A /* libxml2.dylib */; }; 28 | 0252B2DF142ADFC60018B75D /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2DE142ADFC60018B75D /* SenTestingKit.framework */; }; 29 | 0252B2E0142ADFC60018B75D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C3142ADFC60018B75D /* UIKit.framework */; }; 30 | 0252B2E1142ADFC60018B75D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C5142ADFC60018B75D /* Foundation.framework */; }; 31 | 0252B2E2142ADFC60018B75D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C7142ADFC60018B75D /* CoreGraphics.framework */; }; 32 | 02565F9916E6320700A882F9 /* CopyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1413670716D9BEC700501ABB /* CopyTests.m */; }; 33 | 027B3571153C624700A4EDF2 /* DeepChildrenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8EC71467ED9C00024989 /* DeepChildrenTests.m */; }; 34 | 027DAC3314FBF443001BA563 /* RXMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 027DAC2F14FBF443001BA563 /* RXMLElement.m */; }; 35 | 027DAC3614FBF465001BA563 /* RXMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 027DAC2F14FBF443001BA563 /* RXMLElement.m */; }; 36 | 02ADE6A216A0E33A008643D5 /* AttributeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 02ADE6A116A0E33A008643D5 /* AttributeTests.m */; }; 37 | 02ADE6A316A0E491008643D5 /* BoundaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8EC61467ED9C00024989 /* BoundaryTests.m */; }; 38 | 02ADE6A416A0E491008643D5 /* DeepTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8EC81467ED9C00024989 /* DeepTests.m */; }; 39 | 02ADE6A516A0E491008643D5 /* ErrorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8EC91467ED9C00024989 /* ErrorTests.m */; }; 40 | 02ADE6A616A0E491008643D5 /* SimpleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8ECA1467ED9C00024989 /* SimpleTests.m */; }; 41 | 02ADE6A716A0E491008643D5 /* TextConversionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8ECB1467ED9C00024989 /* TextConversionTests.m */; }; 42 | 02ADE6A816A0E491008643D5 /* WildcardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8ECC1467ED9C00024989 /* WildcardTests.m */; }; 43 | 02ADE6A916A0E491008643D5 /* EncodingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 02F3A4041526D7BC00E8C822 /* EncodingTests.m */; }; 44 | 02ADE6AA16A0E491008643D5 /* XPathTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 027B6BCF153C652E00A4EDF2 /* XPathTests.m */; }; 45 | 02F3A3FF1526D22600E8C822 /* players.xml in Resources */ = {isa = PBXBuildFile; fileRef = 0DEB8F2D14681BD800024989 /* players.xml */; }; 46 | 0DEB8EB51467EC9B00024989 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C5142ADFC60018B75D /* Foundation.framework */; }; 47 | 0DEB8F2C14681A9400024989 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B305142AE3FF0018B75D /* libz.dylib */; }; 48 | 5415BE4216FC638100AFC566 /* HTMLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5415BE4116FC638100AFC566 /* HTMLTests.m */; }; 49 | 6BD1BDA91558B91400F1D055 /* RXMLElement.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 027DAC2E14FBF443001BA563 /* RXMLElement.h */; }; 50 | /* End PBXBuildFile section */ 51 | 52 | /* Begin PBXCopyFilesBuildPhase section */ 53 | 6BD1BDA81558B90300F1D055 /* Copy Headers */ = { 54 | isa = PBXCopyFilesBuildPhase; 55 | buildActionMask = 2147483647; 56 | dstPath = "${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal/${PRODUCT_NAME}.framework/Versions/A/Headers/"; 57 | dstSubfolderSpec = 0; 58 | files = ( 59 | 6BD1BDA91558B91400F1D055 /* RXMLElement.h in Copy Headers */, 60 | ); 61 | name = "Copy Headers"; 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXCopyFilesBuildPhase section */ 65 | 66 | /* Begin PBXFileReference section */ 67 | 02041DB71526A71200D1F36A /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; 68 | 02041DC21526D03A00D1F36A /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; 69 | 0252B2C3142ADFC60018B75D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 70 | 0252B2C5142ADFC60018B75D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 71 | 0252B2C7142ADFC60018B75D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 72 | 0252B2DD142ADFC60018B75D /* RaptureXMLTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RaptureXMLTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | 0252B2DE142ADFC60018B75D /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 74 | 0252B305142AE3FF0018B75D /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 75 | 027B6BCF153C652E00A4EDF2 /* XPathTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XPathTests.m; path = Tests/XPathTests.m; sourceTree = SOURCE_ROOT; }; 76 | 027DAC2E14FBF443001BA563 /* RXMLElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RXMLElement.h; sourceTree = ""; }; 77 | 027DAC2F14FBF443001BA563 /* RXMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RXMLElement.m; sourceTree = ""; }; 78 | 027DAC3814FBF4B5001BA563 /* Library-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Library-Prefix.pch"; sourceTree = ""; }; 79 | 02ADE6A116A0E33A008643D5 /* AttributeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AttributeTests.m; sourceTree = SOURCE_ROOT; }; 80 | 02F3A4041526D7BC00E8C822 /* EncodingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EncodingTests.m; sourceTree = SOURCE_ROOT; }; 81 | 0DEB8EB41467EC9B00024989 /* libRaptureXML.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRaptureXML.a; sourceTree = BUILT_PRODUCTS_DIR; }; 82 | 0DEB8EC61467ED9C00024989 /* BoundaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BoundaryTests.m; path = Tests/BoundaryTests.m; sourceTree = SOURCE_ROOT; }; 83 | 0DEB8EC71467ED9C00024989 /* DeepChildrenTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DeepChildrenTests.m; path = Tests/DeepChildrenTests.m; sourceTree = SOURCE_ROOT; }; 84 | 0DEB8EC81467ED9C00024989 /* DeepTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DeepTests.m; path = Tests/DeepTests.m; sourceTree = SOURCE_ROOT; }; 85 | 0DEB8EC91467ED9C00024989 /* ErrorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ErrorTests.m; path = Tests/ErrorTests.m; sourceTree = SOURCE_ROOT; }; 86 | 0DEB8ECA1467ED9C00024989 /* SimpleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SimpleTests.m; path = Tests/SimpleTests.m; sourceTree = SOURCE_ROOT; }; 87 | 0DEB8ECB1467ED9C00024989 /* TextConversionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TextConversionTests.m; path = Tests/TextConversionTests.m; sourceTree = SOURCE_ROOT; }; 88 | 0DEB8ECC1467ED9C00024989 /* WildcardTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WildcardTests.m; path = Tests/WildcardTests.m; sourceTree = SOURCE_ROOT; }; 89 | 0DEB8F2B14681A0800024989 /* Tests-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Tests-Prefix.pch"; path = "Tests/Tests-Prefix.pch"; sourceTree = SOURCE_ROOT; }; 90 | 0DEB8F2D14681BD800024989 /* players.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = players.xml; path = Tests/players.xml; sourceTree = SOURCE_ROOT; }; 91 | 1413670716D9BEC700501ABB /* CopyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CopyTests.m; path = Tests/CopyTests.m; sourceTree = SOURCE_ROOT; }; 92 | 5415BE4116FC638100AFC566 /* HTMLTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTMLTests.m; path = Tests/HTMLTests.m; sourceTree = SOURCE_ROOT; }; 93 | 6BD1BD951558B7A800F1D055 /* RaptureXML-StaticLib-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RaptureXML-StaticLib-Prefix.pch"; sourceTree = ""; }; 94 | /* End PBXFileReference section */ 95 | 96 | /* Begin PBXFrameworksBuildPhase section */ 97 | 0252B2D9142ADFC60018B75D /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | 02041DBA1526B0DE00D1F36A /* libxml2.dylib in Frameworks */, 102 | 0DEB8F2C14681A9400024989 /* libz.dylib in Frameworks */, 103 | 0252B2DF142ADFC60018B75D /* SenTestingKit.framework in Frameworks */, 104 | 0252B2E0142ADFC60018B75D /* UIKit.framework in Frameworks */, 105 | 0252B2E1142ADFC60018B75D /* Foundation.framework in Frameworks */, 106 | 0252B2E2142ADFC60018B75D /* CoreGraphics.framework in Frameworks */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | 0DEB8EB11467EC9B00024989 /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | 02041DB81526A71200D1F36A /* libxml2.dylib in Frameworks */, 115 | 0DEB8EB51467EC9B00024989 /* Foundation.framework in Frameworks */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXFrameworksBuildPhase section */ 120 | 121 | /* Begin PBXGroup section */ 122 | 0252B2B4142ADFC60018B75D = { 123 | isa = PBXGroup; 124 | children = ( 125 | 027DAC3814FBF4B5001BA563 /* Library-Prefix.pch */, 126 | 027DAC2B14FBF443001BA563 /* RaptureXML */, 127 | 0252B2E5142ADFC60018B75D /* Tests */, 128 | 6BD1BD931558B7A800F1D055 /* RaptureXML-StaticLib */, 129 | 0252B2C2142ADFC60018B75D /* Frameworks */, 130 | 0252B2C0142ADFC60018B75D /* Products */, 131 | ); 132 | sourceTree = ""; 133 | }; 134 | 0252B2C0142ADFC60018B75D /* Products */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 0252B2DD142ADFC60018B75D /* RaptureXMLTests.octest */, 138 | 0DEB8EB41467EC9B00024989 /* libRaptureXML.a */, 139 | ); 140 | name = Products; 141 | sourceTree = ""; 142 | }; 143 | 0252B2C2142ADFC60018B75D /* Frameworks */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 02041DC21526D03A00D1F36A /* MediaPlayer.framework */, 147 | 02041DB71526A71200D1F36A /* libxml2.dylib */, 148 | 0252B305142AE3FF0018B75D /* libz.dylib */, 149 | 0252B2C3142ADFC60018B75D /* UIKit.framework */, 150 | 0252B2C5142ADFC60018B75D /* Foundation.framework */, 151 | 0252B2C7142ADFC60018B75D /* CoreGraphics.framework */, 152 | 0252B2DE142ADFC60018B75D /* SenTestingKit.framework */, 153 | ); 154 | name = Frameworks; 155 | sourceTree = ""; 156 | }; 157 | 0252B2E5142ADFC60018B75D /* Tests */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 1413670716D9BEC700501ABB /* CopyTests.m */, 161 | 0DEB8F2D14681BD800024989 /* players.xml */, 162 | 0DEB8F2B14681A0800024989 /* Tests-Prefix.pch */, 163 | 0DEB8EC61467ED9C00024989 /* BoundaryTests.m */, 164 | 0DEB8EC71467ED9C00024989 /* DeepChildrenTests.m */, 165 | 0DEB8EC81467ED9C00024989 /* DeepTests.m */, 166 | 0DEB8EC91467ED9C00024989 /* ErrorTests.m */, 167 | 0DEB8ECA1467ED9C00024989 /* SimpleTests.m */, 168 | 0DEB8ECB1467ED9C00024989 /* TextConversionTests.m */, 169 | 0DEB8ECC1467ED9C00024989 /* WildcardTests.m */, 170 | 02F3A4041526D7BC00E8C822 /* EncodingTests.m */, 171 | 027B6BCF153C652E00A4EDF2 /* XPathTests.m */, 172 | 02ADE6A116A0E33A008643D5 /* AttributeTests.m */, 173 | 5415BE4116FC638100AFC566 /* HTMLTests.m */, 174 | ); 175 | name = Tests; 176 | path = RaptureXMLTests; 177 | sourceTree = ""; 178 | }; 179 | 027DAC2B14FBF443001BA563 /* RaptureXML */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 027DAC2E14FBF443001BA563 /* RXMLElement.h */, 183 | 027DAC2F14FBF443001BA563 /* RXMLElement.m */, 184 | ); 185 | path = RaptureXML; 186 | sourceTree = ""; 187 | }; 188 | 6BD1BD931558B7A800F1D055 /* RaptureXML-StaticLib */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 6BD1BD941558B7A800F1D055 /* Supporting Files */, 192 | ); 193 | path = "RaptureXML-StaticLib"; 194 | sourceTree = ""; 195 | }; 196 | 6BD1BD941558B7A800F1D055 /* Supporting Files */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 6BD1BD951558B7A800F1D055 /* RaptureXML-StaticLib-Prefix.pch */, 200 | ); 201 | name = "Supporting Files"; 202 | sourceTree = ""; 203 | }; 204 | /* End PBXGroup section */ 205 | 206 | /* Begin PBXHeadersBuildPhase section */ 207 | 0DEB8EB21467EC9B00024989 /* Headers */ = { 208 | isa = PBXHeadersBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXHeadersBuildPhase section */ 215 | 216 | /* Begin PBXNativeTarget section */ 217 | 0252B2DC142ADFC60018B75D /* RaptureXMLTests */ = { 218 | isa = PBXNativeTarget; 219 | buildConfigurationList = 0252B2F4142ADFC70018B75D /* Build configuration list for PBXNativeTarget "RaptureXMLTests" */; 220 | buildPhases = ( 221 | 0252B2D8142ADFC60018B75D /* Sources */, 222 | 0252B2D9142ADFC60018B75D /* Frameworks */, 223 | 0252B2DA142ADFC60018B75D /* Resources */, 224 | 0252B2DB142ADFC60018B75D /* ShellScript */, 225 | ); 226 | buildRules = ( 227 | ); 228 | dependencies = ( 229 | ); 230 | name = RaptureXMLTests; 231 | productName = RaptureXMLTests; 232 | productReference = 0252B2DD142ADFC60018B75D /* RaptureXMLTests.octest */; 233 | productType = "com.apple.product-type.bundle"; 234 | }; 235 | 0DEB8EB31467EC9B00024989 /* RaptureXML */ = { 236 | isa = PBXNativeTarget; 237 | buildConfigurationList = 0DEB8EBC1467EC9B00024989 /* Build configuration list for PBXNativeTarget "RaptureXML" */; 238 | buildPhases = ( 239 | 0DEB8EB01467EC9B00024989 /* Sources */, 240 | 0DEB8EB11467EC9B00024989 /* Frameworks */, 241 | 0DEB8EB21467EC9B00024989 /* Headers */, 242 | ); 243 | buildRules = ( 244 | ); 245 | dependencies = ( 246 | ); 247 | name = RaptureXML; 248 | productName = RaptureXML; 249 | productReference = 0DEB8EB41467EC9B00024989 /* libRaptureXML.a */; 250 | productType = "com.apple.product-type.library.static"; 251 | }; 252 | /* End PBXNativeTarget section */ 253 | 254 | /* Begin PBXProject section */ 255 | 0252B2B6142ADFC60018B75D /* Project object */ = { 256 | isa = PBXProject; 257 | attributes = { 258 | LastUpgradeCheck = 0460; 259 | ORGANIZATIONNAME = "Rapture In Venice"; 260 | }; 261 | buildConfigurationList = 0252B2B9142ADFC60018B75D /* Build configuration list for PBXProject "RaptureXML" */; 262 | compatibilityVersion = "Xcode 3.2"; 263 | developmentRegion = English; 264 | hasScannedForEncodings = 0; 265 | knownRegions = ( 266 | en, 267 | English, 268 | de, 269 | el, 270 | es, 271 | fr, 272 | it, 273 | ru, 274 | ); 275 | mainGroup = 0252B2B4142ADFC60018B75D; 276 | productRefGroup = 0252B2C0142ADFC60018B75D /* Products */; 277 | projectDirPath = ""; 278 | projectRoot = ""; 279 | targets = ( 280 | 0DEB8EB31467EC9B00024989 /* RaptureXML */, 281 | 0252B2DC142ADFC60018B75D /* RaptureXMLTests */, 282 | 6BD1BD9D1558B7FA00F1D055 /* RaptureXMLFramework */, 283 | ); 284 | }; 285 | /* End PBXProject section */ 286 | 287 | /* Begin PBXResourcesBuildPhase section */ 288 | 0252B2DA142ADFC60018B75D /* Resources */ = { 289 | isa = PBXResourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | 02F3A3FF1526D22600E8C822 /* players.xml in Resources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | /* End PBXResourcesBuildPhase section */ 297 | 298 | /* Begin PBXShellScriptBuildPhase section */ 299 | 0252B2DB142ADFC60018B75D /* ShellScript */ = { 300 | isa = PBXShellScriptBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | ); 304 | inputPaths = ( 305 | ); 306 | outputPaths = ( 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | shellPath = /bin/sh; 310 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 311 | }; 312 | 6BD1BDA61558B82400F1D055 /* Build static lib */ = { 313 | isa = PBXShellScriptBuildPhase; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | ); 317 | inputPaths = ( 318 | ); 319 | name = "Build static lib"; 320 | outputPaths = ( 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | shellPath = /bin/sh; 324 | shellScript = "/usr/bin/xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build\n/usr/bin/xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build\n"; 325 | }; 326 | 6BD1BDA71558B85A00F1D055 /* Assemble Framework */ = { 327 | isa = PBXShellScriptBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | ); 331 | inputPaths = ( 332 | ); 333 | name = "Assemble Framework"; 334 | outputPaths = ( 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | shellPath = /bin/sh; 338 | shellScript = "PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin\nSIMULATOR_LIBRARY_PATH=\"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a\" &&\nDEVICE_LIBRARY_PATH=\"${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a\" &&\nUNIVERSAL_LIBRARY_DIR=\"${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal\" &&\nUNIVERSAL_LIBRARY_PATH=\"${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}\" &&\nFRAMEWORK=\"${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}.framework\" &&\n\n# Create framework directory structure.\nrm -rf \"${FRAMEWORK}\" &&\nmkdir -p \"${UNIVERSAL_LIBRARY_DIR}\" &&\nmkdir -p \"${FRAMEWORK}/Versions/A/Headers\" &&\nmkdir -p \"${FRAMEWORK}/Versions/A/Resources\" &&\n\n# Generate universal binary from desktop, device, and simulator builds.\nlipo \"${SIMULATOR_LIBRARY_PATH}\" \"${DEVICE_LIBRARY_PATH}\" -create -output \"${UNIVERSAL_LIBRARY_PATH}\" &&\n\n# Move files to appropriate locations in framework paths.\ncp \"${UNIVERSAL_LIBRARY_PATH}\" \"${FRAMEWORK}/Versions/A\" &&\nln -s \"A\" \"${FRAMEWORK}/Versions/Current\" &&\nln -s \"Versions/Current/Headers\" \"${FRAMEWORK}/Headers\" &&\nln -s \"Versions/Current/Resources\" \"${FRAMEWORK}/Resources\" &&\nln -s \"Versions/Current/${PRODUCT_NAME}\" \"${FRAMEWORK}/${PRODUCT_NAME}\"\n#cp \"${SRCROOT}/Resources/Info.plist\" \"${FRAMEWORK}/Resources/Info.plist\""; 339 | }; 340 | /* End PBXShellScriptBuildPhase section */ 341 | 342 | /* Begin PBXSourcesBuildPhase section */ 343 | 0252B2D8142ADFC60018B75D /* Sources */ = { 344 | isa = PBXSourcesBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | 027DAC3314FBF443001BA563 /* RXMLElement.m in Sources */, 348 | 027B3571153C624700A4EDF2 /* DeepChildrenTests.m in Sources */, 349 | 02ADE6A216A0E33A008643D5 /* AttributeTests.m in Sources */, 350 | 02ADE6A316A0E491008643D5 /* BoundaryTests.m in Sources */, 351 | 02ADE6A416A0E491008643D5 /* DeepTests.m in Sources */, 352 | 02ADE6A516A0E491008643D5 /* ErrorTests.m in Sources */, 353 | 02ADE6A616A0E491008643D5 /* SimpleTests.m in Sources */, 354 | 02ADE6A716A0E491008643D5 /* TextConversionTests.m in Sources */, 355 | 02ADE6A816A0E491008643D5 /* WildcardTests.m in Sources */, 356 | 02ADE6A916A0E491008643D5 /* EncodingTests.m in Sources */, 357 | 02ADE6AA16A0E491008643D5 /* XPathTests.m in Sources */, 358 | 02565F9916E6320700A882F9 /* CopyTests.m in Sources */, 359 | 5415BE4216FC638100AFC566 /* HTMLTests.m in Sources */, 360 | ); 361 | runOnlyForDeploymentPostprocessing = 0; 362 | }; 363 | 0DEB8EB01467EC9B00024989 /* Sources */ = { 364 | isa = PBXSourcesBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | 027DAC3614FBF465001BA563 /* RXMLElement.m in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | /* End PBXSourcesBuildPhase section */ 372 | 373 | /* Begin XCBuildConfiguration section */ 374 | 0252B2EF142ADFC70018B75D /* Debug */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | ALWAYS_SEARCH_USER_PATHS = NO; 378 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 379 | CLANG_WARN_CONSTANT_CONVERSION = YES; 380 | CLANG_WARN_ENUM_CONVERSION = YES; 381 | CLANG_WARN_INT_CONVERSION = YES; 382 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 383 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 384 | COPY_PHASE_STRIP = NO; 385 | GCC_C_LANGUAGE_STANDARD = gnu99; 386 | GCC_DYNAMIC_NO_PIC = NO; 387 | GCC_OPTIMIZATION_LEVEL = 0; 388 | GCC_PREPROCESSOR_DEFINITIONS = ( 389 | "DEBUG=1", 390 | "$(inherited)", 391 | ); 392 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 393 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 394 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 395 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 396 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 399 | SDKROOT = iphoneos; 400 | }; 401 | name = Debug; 402 | }; 403 | 0252B2F0142ADFC70018B75D /* Release */ = { 404 | isa = XCBuildConfiguration; 405 | buildSettings = { 406 | ALWAYS_SEARCH_USER_PATHS = NO; 407 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 408 | CLANG_WARN_CONSTANT_CONVERSION = YES; 409 | CLANG_WARN_ENUM_CONVERSION = YES; 410 | CLANG_WARN_INT_CONVERSION = YES; 411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 412 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 413 | COPY_PHASE_STRIP = YES; 414 | GCC_C_LANGUAGE_STANDARD = gnu99; 415 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 416 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 417 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 418 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 419 | GCC_WARN_UNUSED_VARIABLE = YES; 420 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 421 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 422 | SDKROOT = iphoneos; 423 | VALIDATE_PRODUCT = YES; 424 | }; 425 | name = Release; 426 | }; 427 | 0252B2F5142ADFC70018B75D /* Debug */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | CLANG_ENABLE_OBJC_ARC = YES; 431 | FRAMEWORK_SEARCH_PATHS = ( 432 | "$(SDKROOT)/Developer/Library/Frameworks", 433 | "$(DEVELOPER_LIBRARY_DIR)/Frameworks", 434 | ); 435 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 436 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 437 | GCC_VERSION = ""; 438 | HEADER_SEARCH_PATHS = "\"$(SDK_DIR)\"/usr/include/libxml2/**"; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | TEST_AFTER_BUILD = YES; 441 | TEST_HOST = "$(BUNDLE_LOADER)"; 442 | WRAPPER_EXTENSION = octest; 443 | }; 444 | name = Debug; 445 | }; 446 | 0252B2F6142ADFC70018B75D /* Release */ = { 447 | isa = XCBuildConfiguration; 448 | buildSettings = { 449 | CLANG_ENABLE_OBJC_ARC = YES; 450 | FRAMEWORK_SEARCH_PATHS = ( 451 | "$(SDKROOT)/Developer/Library/Frameworks", 452 | "$(DEVELOPER_LIBRARY_DIR)/Frameworks", 453 | ); 454 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 455 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 456 | GCC_VERSION = ""; 457 | HEADER_SEARCH_PATHS = "\"$(SDK_DIR)\"/usr/include/libxml2/**"; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | TEST_AFTER_BUILD = YES; 460 | TEST_HOST = "$(BUNDLE_LOADER)"; 461 | WRAPPER_EXTENSION = octest; 462 | }; 463 | name = Release; 464 | }; 465 | 0DEB8EBD1467EC9B00024989 /* Debug */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | CLANG_ENABLE_OBJC_ARC = YES; 469 | DSTROOT = /tmp/RaptureXML.dst; 470 | FRAMEWORK_SEARCH_PATHS = ( 471 | "$(inherited)", 472 | "\"$(SRCROOT)/../.metadata/.plugins/org.eclipse.debug.core/.launches/System/Library/Frameworks\"", 473 | "\"$(SRCROOT)/../Cognitive\"", 474 | ); 475 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 476 | GCC_PREFIX_HEADER = "Library-Prefix.pch"; 477 | GCC_VERSION = ""; 478 | HEADER_SEARCH_PATHS = "\"$(SDK_DIR)\"/usr/include/libxml2/**"; 479 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 480 | LIBRARY_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "\"$(SRCROOT)/../FuzzAlert/AdMob\"", 483 | "\"$(SRCROOT)/../FuzzAlert/FlurryLibWithLocation\"", 484 | "\"$(SRCROOT)/../FuzzAlert/libGHUnitIPhone4_0-0.4.21\"", 485 | "\"$(SRCROOT)/../FuzzAlert/three20/Build/Products/Debug-iphonesimulator\"", 486 | "\"$(SRCROOT)/../FuzzAlert/three20/Build/Products/Release-iphonesimulator\"", 487 | "\"$(SRCROOT)/../InnerBand/libGHUnitIPhone4_0-0.4.22\"", 488 | "\"$(SRCROOT)/../TaskList/FlurryLib\"", 489 | "\"$(SRCROOT)/../WordsWithPractice/WordsWithPractice/GoogleAdMobAdsSDK\"", 490 | ); 491 | PRODUCT_NAME = "$(TARGET_NAME)"; 492 | SKIP_INSTALL = YES; 493 | }; 494 | name = Debug; 495 | }; 496 | 0DEB8EBE1467EC9B00024989 /* Release */ = { 497 | isa = XCBuildConfiguration; 498 | buildSettings = { 499 | CLANG_ENABLE_OBJC_ARC = YES; 500 | DSTROOT = /tmp/RaptureXML.dst; 501 | FRAMEWORK_SEARCH_PATHS = ( 502 | "$(inherited)", 503 | "\"$(SRCROOT)/../.metadata/.plugins/org.eclipse.debug.core/.launches/System/Library/Frameworks\"", 504 | "\"$(SRCROOT)/../Cognitive\"", 505 | ); 506 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 507 | GCC_PREFIX_HEADER = "Library-Prefix.pch"; 508 | GCC_VERSION = ""; 509 | HEADER_SEARCH_PATHS = "\"$(SDK_DIR)\"/usr/include/libxml2/**"; 510 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 511 | LIBRARY_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "\"$(SRCROOT)/../FuzzAlert/AdMob\"", 514 | "\"$(SRCROOT)/../FuzzAlert/FlurryLibWithLocation\"", 515 | "\"$(SRCROOT)/../FuzzAlert/libGHUnitIPhone4_0-0.4.21\"", 516 | "\"$(SRCROOT)/../FuzzAlert/three20/Build/Products/Debug-iphonesimulator\"", 517 | "\"$(SRCROOT)/../FuzzAlert/three20/Build/Products/Release-iphonesimulator\"", 518 | "\"$(SRCROOT)/../InnerBand/libGHUnitIPhone4_0-0.4.22\"", 519 | "\"$(SRCROOT)/../TaskList/FlurryLib\"", 520 | "\"$(SRCROOT)/../WordsWithPractice/WordsWithPractice/GoogleAdMobAdsSDK\"", 521 | ); 522 | PRODUCT_NAME = "$(TARGET_NAME)"; 523 | SKIP_INSTALL = YES; 524 | }; 525 | name = Release; 526 | }; 527 | 6BD1BD9F1558B7FA00F1D055 /* Debug */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | PRODUCT_NAME = RaptureXML; 531 | }; 532 | name = Debug; 533 | }; 534 | 6BD1BDA01558B7FA00F1D055 /* Release */ = { 535 | isa = XCBuildConfiguration; 536 | buildSettings = { 537 | PRODUCT_NAME = RaptureXML; 538 | }; 539 | name = Release; 540 | }; 541 | /* End XCBuildConfiguration section */ 542 | 543 | /* Begin XCConfigurationList section */ 544 | 0252B2B9142ADFC60018B75D /* Build configuration list for PBXProject "RaptureXML" */ = { 545 | isa = XCConfigurationList; 546 | buildConfigurations = ( 547 | 0252B2EF142ADFC70018B75D /* Debug */, 548 | 0252B2F0142ADFC70018B75D /* Release */, 549 | ); 550 | defaultConfigurationIsVisible = 0; 551 | defaultConfigurationName = Release; 552 | }; 553 | 0252B2F4142ADFC70018B75D /* Build configuration list for PBXNativeTarget "RaptureXMLTests" */ = { 554 | isa = XCConfigurationList; 555 | buildConfigurations = ( 556 | 0252B2F5142ADFC70018B75D /* Debug */, 557 | 0252B2F6142ADFC70018B75D /* Release */, 558 | ); 559 | defaultConfigurationIsVisible = 0; 560 | defaultConfigurationName = Release; 561 | }; 562 | 0DEB8EBC1467EC9B00024989 /* Build configuration list for PBXNativeTarget "RaptureXML" */ = { 563 | isa = XCConfigurationList; 564 | buildConfigurations = ( 565 | 0DEB8EBD1467EC9B00024989 /* Debug */, 566 | 0DEB8EBE1467EC9B00024989 /* Release */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | 6BD1BD9E1558B7FA00F1D055 /* Build configuration list for PBXAggregateTarget "RaptureXMLFramework" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | 6BD1BD9F1558B7FA00F1D055 /* Debug */, 575 | 6BD1BDA01558B7FA00F1D055 /* Release */, 576 | ); 577 | defaultConfigurationIsVisible = 0; 578 | defaultConfigurationName = Release; 579 | }; 580 | /* End XCConfigurationList section */ 581 | }; 582 | rootObject = 0252B2B6142ADFC60018B75D /* Project object */; 583 | } 584 | -------------------------------------------------------------------------------- /RaptureXML/RXMLElement.h: -------------------------------------------------------------------------------- 1 | // ================================================================================================ 2 | // RXMLElement.h 3 | // Fast processing of XML files 4 | // 5 | // ================================================================================================ 6 | // Created by John Blanco on 9/23/11. 7 | // Version 1.4 8 | // 9 | // Copyright (c) 2011 John Blanco 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | // ================================================================================================ 29 | // 30 | 31 | #import 32 | #import 33 | #import 34 | #import 35 | #import 36 | #import 37 | 38 | @interface RXMLDocHolder : NSObject { 39 | xmlDocPtr doc_; 40 | } 41 | 42 | - (id)initWithDocPtr:(xmlDocPtr)doc; 43 | - (xmlDocPtr)doc; 44 | 45 | @end 46 | 47 | @interface RXMLElement : NSObject { 48 | xmlNodePtr node_; 49 | } 50 | 51 | - (id)initFromXMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding; 52 | - (id)initFromXMLFile:(NSString *)filename; 53 | - (id)initFromXMLFile:(NSString *)filename fileExtension:(NSString*)extension; 54 | - (id)initFromXMLFilePath:(NSString *)fullPath; 55 | - (id)initFromURL:(NSURL *)url __attribute__((deprecated)); 56 | - (id)initFromXMLData:(NSData *)data; 57 | - (id)initFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node; 58 | 59 | - (id)initFromHTMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding; 60 | - (id)initFromHTMLFile:(NSString *)filename; 61 | - (id)initFromHTMLFile:(NSString *)filename fileExtension:(NSString*)extension; 62 | - (id)initFromHTMLFilePath:(NSString *)fullPath; 63 | - (id)initFromHTMLData:(NSData *)data; 64 | 65 | + (id)elementFromXMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding; 66 | + (id)elementFromXMLFile:(NSString *)filename; 67 | + (id)elementFromXMLFilename:(NSString *)filename fileExtension:(NSString *)extension; 68 | + (id)elementFromXMLFilePath:(NSString *)fullPath; 69 | + (id)elementFromURL:(NSURL *)url __attribute__((deprecated)); 70 | + (id)elementFromXMLData:(NSData *)data; 71 | + (id)elementFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node; 72 | 73 | + (id)elementFromHTMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding; 74 | + (id)elementFromHTMLFile:(NSString *)filename; 75 | + (id)elementFromHTMLFile:(NSString *)filename fileExtension:(NSString*)extension; 76 | + (id)elementFromHTMLFilePath:(NSString *)fullPath; 77 | + (id)elementFromHTMLData:(NSData *)data; 78 | 79 | - (NSString *)attribute:(NSString *)attributeName; 80 | - (NSString *)attribute:(NSString *)attributeName inNamespace:(NSString *)ns; 81 | 82 | - (NSArray *)attributeNames; 83 | 84 | - (NSInteger)attributeAsInt:(NSString *)attributeName; 85 | - (NSInteger)attributeAsInt:(NSString *)attributeName inNamespace:(NSString *)ns; 86 | 87 | - (double)attributeAsDouble:(NSString *)attributeName; 88 | - (double)attributeAsDouble:(NSString *)attributeName inNamespace:(NSString *)ns; 89 | 90 | - (RXMLElement *)child:(NSString *)tag; 91 | - (RXMLElement *)child:(NSString *)tag inNamespace:(NSString *)ns; 92 | 93 | - (NSArray *)children:(NSString *)tag; 94 | - (NSArray *)children:(NSString *)tag inNamespace:(NSString *)ns; 95 | - (NSArray *)childrenWithRootXPath:(NSString *)xpath; 96 | 97 | - (void)iterate:(NSString *)query usingBlock:(void (^)(RXMLElement *))blk; 98 | - (void)iterateWithRootXPath:(NSString *)xpath usingBlock:(void (^)(RXMLElement *))blk; 99 | - (void)iterateElements:(NSArray *)elements usingBlock:(void (^)(RXMLElement *))blk; 100 | 101 | @property (nonatomic, strong) RXMLDocHolder *xmlDoc; 102 | @property (nonatomic, readonly) NSString *tag; 103 | @property (nonatomic, readonly) NSString *text; 104 | @property (nonatomic, readonly) NSString *xml; 105 | @property (nonatomic, readonly) NSString *innerXml; 106 | @property (nonatomic, readonly) NSInteger textAsInt; 107 | @property (nonatomic, readonly) double textAsDouble; 108 | @property (nonatomic, readonly) BOOL isValid; 109 | 110 | @end 111 | 112 | typedef void (^RXMLBlock)(RXMLElement *element); 113 | 114 | -------------------------------------------------------------------------------- /RaptureXML/RXMLElement.m: -------------------------------------------------------------------------------- 1 | // ================================================================================================ 2 | // RXMLElement.m 3 | // Fast processing of XML files 4 | // 5 | // ================================================================================================ 6 | // Created by John Blanco on 9/23/11. 7 | // Version 1.4 8 | // 9 | // Copyright (c) 2011 John Blanco 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | // ================================================================================================ 29 | // 30 | 31 | #import "RXMLElement.h" 32 | 33 | @implementation RXMLDocHolder 34 | 35 | - (id)initWithDocPtr:(xmlDocPtr)doc { 36 | if ((self = [super init])) { 37 | doc_ = doc; 38 | } 39 | 40 | return self; 41 | } 42 | 43 | - (void)dealloc { 44 | if (doc_ != nil) { 45 | xmlFreeDoc(doc_); 46 | } 47 | } 48 | 49 | - (xmlDocPtr)doc { 50 | return doc_; 51 | } 52 | 53 | @end 54 | 55 | @implementation RXMLElement 56 | 57 | - (id)initFromXMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding { 58 | return [self initFromXMLData:[xmlString dataUsingEncoding:encoding]]; 59 | } 60 | 61 | - (id)initFromXMLFilePath:(NSString *)fullPath { 62 | return [self initFromXMLData:[NSData dataWithContentsOfFile:fullPath]]; 63 | } 64 | 65 | - (id)initFromXMLFile:(NSString *)filename { 66 | NSString *fullPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:filename]; 67 | return [self initFromXMLFilePath:fullPath]; 68 | } 69 | 70 | - (id)initFromXMLFile:(NSString *)filename fileExtension:(NSString *)extension { 71 | NSString *fullPath = [[NSBundle mainBundle] pathForResource:filename ofType:extension]; 72 | return [self initFromXMLData:[NSData dataWithContentsOfFile:fullPath]]; 73 | } 74 | 75 | - (id)initFromURL:(NSURL *)url { 76 | return [self initFromXMLData:[NSData dataWithContentsOfURL:url]]; 77 | } 78 | 79 | - (id)initFromXMLData:(NSData *)data { 80 | if ((self = [super init])) { 81 | xmlDocPtr doc = xmlReadMemory([data bytes], (int)[data length], "", nil, XML_PARSE_RECOVER|XML_PARSE_NOENT); 82 | self.xmlDoc = [[RXMLDocHolder alloc] initWithDocPtr:doc]; 83 | 84 | if ([self isValid]) { 85 | node_ = xmlDocGetRootElement(doc); 86 | 87 | if (!node_) { 88 | self.xmlDoc = nil; 89 | } 90 | } 91 | } 92 | 93 | return self; 94 | } 95 | 96 | - (id)initFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node { 97 | if ((self = [super init])) { 98 | self.xmlDoc = doc; 99 | node_ = node; 100 | } 101 | 102 | return self; 103 | } 104 | 105 | - (id)initFromHTMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding { 106 | return [self initFromHTMLData:[xmlString dataUsingEncoding:encoding]]; 107 | } 108 | 109 | - (id)initFromHTMLFile:(NSString *)filename { 110 | NSString *fullPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:filename]; 111 | return [self initFromHTMLData:[NSData dataWithContentsOfFile:fullPath]]; 112 | } 113 | 114 | - (id)initFromHTMLFile:(NSString *)filename fileExtension:(NSString*)extension { 115 | NSString *fullPath = [[NSBundle mainBundle] pathForResource:filename ofType:extension]; 116 | return [self initFromHTMLData:[NSData dataWithContentsOfFile:fullPath]]; 117 | } 118 | 119 | - (id)initFromHTMLFilePath:(NSString *)fullPath { 120 | return [self initFromHTMLData:[NSData dataWithContentsOfFile:fullPath]]; 121 | 122 | } 123 | 124 | - (id)initFromHTMLData:(NSData *)data { 125 | if ((self = [super init])) { 126 | xmlDocPtr doc = htmlReadMemory([data bytes], (int)[data length], "", nil, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR); 127 | self.xmlDoc = [[RXMLDocHolder alloc] initWithDocPtr:doc]; 128 | 129 | if ([self isValid]) { 130 | node_ = xmlDocGetRootElement(doc); 131 | 132 | if (!node_) { 133 | self.xmlDoc = nil; 134 | } 135 | } 136 | } 137 | return self; 138 | } 139 | 140 | 141 | // Copy the RaptureXML element 142 | // (calling copy will call this method automatically with the default zone) 143 | -(id)copyWithZone:(NSZone *)zone{ 144 | RXMLElement* new_element = [[RXMLElement alloc] init]; 145 | new_element->node_ = node_; 146 | new_element.xmlDoc = self.xmlDoc; 147 | return new_element; 148 | } 149 | 150 | + (id)elementFromXMLString:(NSString *)attributeXML_ encoding:(NSStringEncoding)encoding { 151 | return [[RXMLElement alloc] initFromXMLString:attributeXML_ encoding:encoding]; 152 | } 153 | 154 | + (id)elementFromXMLFilePath:(NSString *)fullPath { 155 | return [[RXMLElement alloc] initFromXMLFilePath:fullPath]; 156 | } 157 | 158 | + (id)elementFromXMLFile:(NSString *)filename { 159 | return [[RXMLElement alloc] initFromXMLFile:filename]; 160 | } 161 | 162 | + (id)elementFromXMLFilename:(NSString *)filename fileExtension:(NSString *)extension { 163 | return [[RXMLElement alloc] initFromXMLFile:filename fileExtension:extension]; 164 | } 165 | 166 | + (id)elementFromURL:(NSURL *)url { 167 | return [[RXMLElement alloc] initFromURL:url]; 168 | } 169 | 170 | + (id)elementFromXMLData:(NSData *)data { 171 | return [[RXMLElement alloc] initFromXMLData:data]; 172 | } 173 | 174 | + (id)elementFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node { 175 | return [[RXMLElement alloc] initFromXMLDoc:doc node:node]; 176 | } 177 | 178 | - (NSString *)description { 179 | return [self text]; 180 | } 181 | 182 | + (id)elementFromHTMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding { 183 | return [[RXMLElement alloc] initFromHTMLString:xmlString encoding:encoding]; 184 | } 185 | 186 | + (id)elementFromHTMLFile:(NSString *)filename { 187 | return [[RXMLElement alloc] initFromHTMLFile:filename]; 188 | } 189 | 190 | + (id)elementFromHTMLFile:(NSString *)filename fileExtension:(NSString*)extension { 191 | return [[RXMLElement alloc] initFromHTMLFile:filename fileExtension:extension]; 192 | } 193 | 194 | + (id)elementFromHTMLFilePath:(NSString *)fullPath { 195 | return [[RXMLElement alloc] initFromHTMLFilePath:fullPath]; 196 | } 197 | 198 | + (id)elementFromHTMLData:(NSData *)data { 199 | return [[RXMLElement alloc] initFromHTMLData:data]; 200 | } 201 | 202 | #pragma mark - 203 | 204 | - (NSString *)tag { 205 | if (node_) { 206 | return [NSString stringWithUTF8String:(const char *)node_->name]; 207 | } else { 208 | return nil; 209 | } 210 | } 211 | 212 | - (NSString *)text { 213 | xmlChar *key = xmlNodeGetContent(node_); 214 | NSString *text = (key ? [NSString stringWithUTF8String:(const char *)key] : @""); 215 | xmlFree(key); 216 | 217 | return text; 218 | } 219 | 220 | - (NSString *)xml { 221 | xmlBufferPtr buffer = xmlBufferCreate(); 222 | xmlNodeDump(buffer, node_->doc, node_, 0, false); 223 | NSString *text = [NSString stringWithUTF8String:(const char *)xmlBufferContent(buffer)]; 224 | xmlBufferFree(buffer); 225 | return text; 226 | } 227 | 228 | - (NSString *)innerXml { 229 | NSMutableString* innerXml = [NSMutableString string]; 230 | xmlNodePtr cur = node_->children; 231 | 232 | while (cur != nil) { 233 | if (cur->type == XML_TEXT_NODE) { 234 | xmlChar *key = xmlNodeGetContent(cur); 235 | NSString *text = (key ? [NSString stringWithUTF8String:(const char *)key] : @""); 236 | xmlFree(key); 237 | [innerXml appendString:text]; 238 | } else { 239 | xmlBufferPtr buffer = xmlBufferCreate(); 240 | xmlNodeDump(buffer, node_->doc, cur, 0, false); 241 | NSString *text = [NSString stringWithUTF8String:(const char *)xmlBufferContent(buffer)]; 242 | xmlBufferFree(buffer); 243 | [innerXml appendString:text]; 244 | } 245 | cur = cur->next; 246 | } 247 | 248 | return innerXml; 249 | } 250 | 251 | - (NSInteger)textAsInt { 252 | return [self.text intValue]; 253 | } 254 | 255 | - (double)textAsDouble { 256 | return [self.text doubleValue]; 257 | } 258 | 259 | - (NSString *)attribute:(NSString *)attName { 260 | NSString *ret = nil; 261 | const unsigned char *attCStr = xmlGetProp(node_, (const xmlChar *)[attName cStringUsingEncoding:NSUTF8StringEncoding]); 262 | 263 | if (attCStr) { 264 | ret = [NSString stringWithUTF8String:(const char *)attCStr]; 265 | xmlFree((void *)attCStr); 266 | } 267 | 268 | return ret; 269 | } 270 | 271 | - (NSString *)attribute:(NSString *)attName inNamespace:(NSString *)ns { 272 | const unsigned char *attCStr = xmlGetNsProp(node_, (const xmlChar *)[attName cStringUsingEncoding:NSUTF8StringEncoding], (const xmlChar *)[ns cStringUsingEncoding:NSUTF8StringEncoding]); 273 | 274 | if (attCStr) { 275 | return [NSString stringWithUTF8String:(const char *)attCStr]; 276 | } 277 | 278 | return nil; 279 | } 280 | 281 | - (NSArray *)attributeNames { 282 | NSMutableArray *names = [[NSMutableArray alloc] init]; 283 | 284 | for(xmlAttrPtr attr = node_->properties; attr != nil; attr = attr->next) { 285 | [names addObject:[[NSString alloc] initWithCString:(const char *)attr->name encoding:NSUTF8StringEncoding]]; 286 | } 287 | 288 | return names; 289 | } 290 | 291 | - (NSInteger)attributeAsInt:(NSString *)attName { 292 | return [[self attribute:attName] intValue]; 293 | } 294 | 295 | - (NSInteger)attributeAsInt:(NSString *)attName inNamespace:(NSString *)ns { 296 | return [[self attribute:attName inNamespace:ns] intValue]; 297 | } 298 | 299 | - (double)attributeAsDouble:(NSString *)attName { 300 | return [[self attribute:attName] doubleValue]; 301 | } 302 | 303 | - (double)attributeAsDouble:(NSString *)attName inNamespace:(NSString *)ns { 304 | return [[self attribute:attName inNamespace:ns] doubleValue]; 305 | } 306 | 307 | - (BOOL)isValid { 308 | return (self.xmlDoc != nil); 309 | } 310 | 311 | #pragma mark - 312 | 313 | - (RXMLElement *)child:(NSString *)tag { 314 | NSArray *components = [tag componentsSeparatedByString:@"."]; 315 | xmlNodePtr cur = node_; 316 | 317 | if (!cur) return nil; 318 | 319 | // navigate down 320 | for (NSString *itag in components) { 321 | const xmlChar *tagC = (const xmlChar *)[itag cStringUsingEncoding:NSUTF8StringEncoding]; 322 | 323 | if ([itag isEqualToString:@"*"]) { 324 | cur = cur->children; 325 | 326 | while (cur != nil && cur->type != XML_ELEMENT_NODE) { 327 | cur = cur->next; 328 | } 329 | } else { 330 | cur = cur->children; 331 | while (cur != nil) { 332 | if (cur->type == XML_ELEMENT_NODE && !xmlStrcmp(cur->name, tagC)) { 333 | break; 334 | } 335 | 336 | cur = cur->next; 337 | } 338 | } 339 | 340 | if (!cur) { 341 | break; 342 | } 343 | } 344 | 345 | if (cur) { 346 | return [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]; 347 | } 348 | 349 | return nil; 350 | } 351 | 352 | - (RXMLElement *)child:(NSString *)tag inNamespace:(NSString *)ns { 353 | NSArray *components = [tag componentsSeparatedByString:@"."]; 354 | xmlNodePtr cur = node_; 355 | const xmlChar *namespaceC = (const xmlChar *)[ns cStringUsingEncoding:NSUTF8StringEncoding]; 356 | 357 | // navigate down 358 | for (NSString *itag in components) { 359 | const xmlChar *tagC = (const xmlChar *)[itag cStringUsingEncoding:NSUTF8StringEncoding]; 360 | 361 | if ([itag isEqualToString:@"*"]) { 362 | cur = cur->children; 363 | 364 | while (cur != nil && cur->type != XML_ELEMENT_NODE && !xmlStrcmp(cur->ns->href, namespaceC)) { 365 | cur = cur->next; 366 | } 367 | } else { 368 | cur = cur->children; 369 | while (cur != nil) { 370 | if (cur->ns != nil) { 371 | if (cur->type == XML_ELEMENT_NODE && 372 | !xmlStrcmp(cur->name, tagC) && 373 | !xmlStrcmp(cur->ns->href, namespaceC)) { 374 | break; 375 | } 376 | } else { 377 | if (cur->type == XML_ELEMENT_NODE && 378 | !xmlStrcmp(cur->name, tagC) && 379 | !xmlStrcmp(namespaceC, nil)) { 380 | break; 381 | } 382 | } 383 | 384 | 385 | cur = cur->next; 386 | } 387 | } 388 | 389 | if (!cur) { 390 | break; 391 | } 392 | } 393 | 394 | if (cur) { 395 | return [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]; 396 | } 397 | 398 | return nil; 399 | } 400 | 401 | - (NSArray *)children:(NSString *)tag { 402 | const xmlChar *tagC = (const xmlChar *)[tag cStringUsingEncoding:NSUTF8StringEncoding]; 403 | NSMutableArray *children = [NSMutableArray array]; 404 | xmlNodePtr cur = node_->children; 405 | 406 | while (cur != nil) { 407 | if (cur->type == XML_ELEMENT_NODE && !xmlStrcmp(cur->name, tagC)) { 408 | [children addObject:[RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]]; 409 | } 410 | 411 | cur = cur->next; 412 | } 413 | 414 | return [children copy]; 415 | } 416 | 417 | - (NSArray *)children:(NSString *)tag inNamespace:(NSString *)ns { 418 | const xmlChar *tagC = (const xmlChar *)[tag cStringUsingEncoding:NSUTF8StringEncoding]; 419 | const xmlChar *namespaceC = (const xmlChar *)[ns cStringUsingEncoding:NSUTF8StringEncoding]; 420 | NSMutableArray *children = [NSMutableArray array]; 421 | xmlNodePtr cur = node_->children; 422 | 423 | while (cur != nil) { 424 | if (cur->type == XML_ELEMENT_NODE && !xmlStrcmp(cur->name, tagC) && !xmlStrcmp(cur->ns->href, namespaceC)) { 425 | [children addObject:[RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]]; 426 | } 427 | 428 | cur = cur->next; 429 | } 430 | 431 | return [children copy]; 432 | } 433 | 434 | - (NSArray *)childrenWithRootXPath:(NSString *)xpath { 435 | // check for a query 436 | if (!xpath) { 437 | return [NSArray array]; 438 | } 439 | 440 | xmlXPathContextPtr context = xmlXPathNewContext([self.xmlDoc doc]); 441 | 442 | if (context == NULL) { 443 | return nil; 444 | } 445 | 446 | xmlXPathObjectPtr object = xmlXPathEvalExpression((xmlChar *)[xpath cStringUsingEncoding:NSUTF8StringEncoding], context); 447 | if(object == NULL) { 448 | return nil; 449 | } 450 | 451 | xmlNodeSetPtr nodes = object->nodesetval; 452 | if (nodes == NULL) { 453 | return nil; 454 | } 455 | 456 | NSMutableArray *resultNodes = [NSMutableArray array]; 457 | 458 | for (NSInteger i = 0; i < nodes->nodeNr; i++) { 459 | RXMLElement *element = [RXMLElement elementFromXMLDoc:self.xmlDoc node:nodes->nodeTab[i]]; 460 | 461 | if (element != NULL) { 462 | [resultNodes addObject:element]; 463 | } 464 | } 465 | 466 | xmlXPathFreeObject(object); 467 | xmlXPathFreeContext(context); 468 | 469 | return resultNodes; 470 | } 471 | 472 | #pragma mark - 473 | 474 | - (void)iterate:(NSString *)query usingBlock:(void (^)(RXMLElement *))blk { 475 | // check for a query 476 | if (!query) { 477 | return; 478 | } 479 | 480 | NSArray *components = [query componentsSeparatedByString:@"."]; 481 | xmlNodePtr cur = node_; 482 | 483 | // navigate down 484 | for (NSInteger i=0; i < components.count; ++i) { 485 | NSString *iTagName = [components objectAtIndex:i]; 486 | 487 | if ([iTagName isEqualToString:@"*"]) { 488 | cur = cur->children; 489 | 490 | // different behavior depending on if this is the end of the query or midstream 491 | if (i < (components.count - 1) && cur != nil) { 492 | // midstream 493 | do { 494 | if (cur->type == XML_ELEMENT_NODE) { 495 | RXMLElement *element = [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]; 496 | NSString *restOfQuery = [[components subarrayWithRange:NSMakeRange(i + 1, components.count - i - 1)] componentsJoinedByString:@"."]; 497 | [element iterate:restOfQuery usingBlock:blk]; 498 | } 499 | 500 | cur = cur->next; 501 | } while (cur != nil); 502 | 503 | } 504 | } else { 505 | const xmlChar *tagNameC = (const xmlChar *)[iTagName cStringUsingEncoding:NSUTF8StringEncoding]; 506 | 507 | cur = cur->children; 508 | while (cur != nil) { 509 | if (cur->type == XML_ELEMENT_NODE && !xmlStrcmp(cur->name, tagNameC)) { 510 | break; 511 | } 512 | 513 | cur = cur->next; 514 | } 515 | } 516 | 517 | if (!cur) { 518 | break; 519 | } 520 | } 521 | 522 | if (cur) { 523 | // enumerate 524 | NSString *childTagName = [components lastObject]; 525 | 526 | do { 527 | if (cur->type == XML_ELEMENT_NODE) { 528 | RXMLElement *element = [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]; 529 | blk(element); 530 | } 531 | 532 | if ([childTagName isEqualToString:@"*"]) { 533 | cur = cur->next; 534 | } else { 535 | const xmlChar *tagNameC = (const xmlChar *)[childTagName cStringUsingEncoding:NSUTF8StringEncoding]; 536 | 537 | while ((cur = cur->next)) { 538 | if (cur->type == XML_ELEMENT_NODE && !xmlStrcmp(cur->name, tagNameC)) { 539 | break; 540 | } 541 | } 542 | } 543 | } while (cur); 544 | } 545 | } 546 | 547 | - (void)iterateWithRootXPath:(NSString *)xpath usingBlock:(void (^)(RXMLElement *))blk { 548 | NSArray *children = [self childrenWithRootXPath:xpath]; 549 | [self iterateElements:children usingBlock:blk]; 550 | } 551 | 552 | - (void)iterateElements:(NSArray *)elements usingBlock:(void (^)(RXMLElement *))blk { 553 | for (RXMLElement *iElement in elements) { 554 | blk(iElement); 555 | } 556 | } 557 | 558 | @end 559 | -------------------------------------------------------------------------------- /Tests/BoundaryTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BoundaryTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface BoundaryTests : SenTestCase { 12 | NSString *emptyXML_; 13 | NSString *emptyTopTagXML_; 14 | NSString *childXML_; 15 | NSString *childrenXML_; 16 | NSString *attributeXML_; 17 | NSString *namespaceXML_; 18 | } 19 | 20 | @end 21 | 22 | 23 | 24 | @implementation BoundaryTests 25 | 26 | - (void)setUp { 27 | emptyXML_ = @""; 28 | emptyTopTagXML_ = @""; 29 | childXML_ = @"foo"; 30 | childrenXML_ = @""; 31 | attributeXML_ = @""; 32 | namespaceXML_ = @"something"; 33 | } 34 | 35 | - (void)testEmptyXML { 36 | RXMLElement *rxml = [RXMLElement elementFromXMLString:emptyXML_ encoding:NSUTF8StringEncoding]; 37 | STAssertFalse(rxml.isValid, nil); 38 | } 39 | 40 | - (void)testEmptyTopTagXML { 41 | RXMLElement *rxml = [RXMLElement elementFromXMLString:emptyTopTagXML_ encoding:NSUTF8StringEncoding]; 42 | STAssertTrue(rxml.isValid, nil); 43 | STAssertEqualObjects(rxml.text, @"", nil); 44 | STAssertEqualObjects([rxml childrenWithRootXPath:@"*"], [NSArray array], nil); 45 | } 46 | 47 | - (void)testAttribute { 48 | RXMLElement *rxml = [RXMLElement elementFromXMLString:attributeXML_ encoding:NSUTF8StringEncoding]; 49 | STAssertTrue(rxml.isValid, nil); 50 | STAssertEqualObjects([rxml attribute:@"foo"], @"bar", nil); 51 | } 52 | 53 | - (void)testNamespaceAttribute { 54 | RXMLElement *rxml = [RXMLElement elementFromXMLString:namespaceXML_ encoding:NSUTF8StringEncoding]; 55 | STAssertTrue(rxml.isValid, nil); 56 | STAssertEqualObjects([rxml attribute:@"foo" inNamespace:@"*"], @"bar", nil); 57 | STAssertEquals([rxml attributeAsInt:@"one" inNamespace:@"*"], 1, nil); 58 | } 59 | 60 | - (void)testChild { 61 | RXMLElement *rxml = [RXMLElement elementFromXMLString:childXML_ encoding:NSUTF8StringEncoding]; 62 | STAssertTrue(rxml.isValid, nil); 63 | STAssertEqualObjects([rxml child:@"empty_child"].text, @"", nil); 64 | STAssertEqualObjects([rxml child:@"text_child"].text, @"foo", nil); 65 | } 66 | 67 | - (void)testNamespaceChild { 68 | RXMLElement *rxml = [RXMLElement elementFromXMLString:namespaceXML_ encoding:NSUTF8StringEncoding]; 69 | STAssertTrue(rxml.isValid, nil); 70 | STAssertEqualObjects([rxml child:@"text" inNamespace:@"*"].text, @"something", nil); 71 | } 72 | 73 | - (void)testChildren { 74 | RXMLElement *rxml = [RXMLElement elementFromXMLString:childrenXML_ encoding:NSUTF8StringEncoding]; 75 | STAssertTrue(rxml.isValid, nil); 76 | STAssertEquals([rxml children:@"child"].count, 3U, nil); 77 | } 78 | 79 | - (void)testNamespaceChildren { 80 | RXMLElement *rxml = [RXMLElement elementFromXMLString:namespaceXML_ encoding:NSUTF8StringEncoding]; 81 | STAssertTrue(rxml.isValid, nil); 82 | STAssertEquals([rxml children:@"text" inNamespace:@"*"].count, 1U, nil); 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /Tests/CopyTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CopyTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copy tests modified from SimpleTests.m by Graham Ramsey on 2/23/13 7 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 8 | // 9 | 10 | #import "RXMLElement.h" 11 | 12 | @interface CopyTests : SenTestCase { 13 | NSString *simplifiedXML_; 14 | NSString *attributedXML_; 15 | NSString *interruptedTextXML_; 16 | NSString *cdataXML_; 17 | } 18 | 19 | @end 20 | 21 | @implementation CopyTests 22 | 23 | - (void)setUp { 24 | simplifiedXML_ = @"\ 25 | \ 26 | Square\ 27 | Triangle\ 28 | Circle\ 29 | "; 30 | 31 | attributedXML_ = @"\ 32 | \ 33 | \ 34 | \ 35 | \ 36 | "; 37 | interruptedTextXML_ = @"thisisinterruptedtext"; 38 | cdataXML_ = @""; 39 | } 40 | 41 | - (void)testInterruptedText { 42 | RXMLElement *rxml = [RXMLElement elementFromXMLString:interruptedTextXML_ encoding:NSUTF8StringEncoding]; 43 | RXMLElement *rxml2 = [rxml copy]; 44 | STAssertEqualObjects(rxml2.text, @"thisisinterruptedtext", nil); 45 | } 46 | 47 | - (void)testCDataText { 48 | RXMLElement *rxml = [RXMLElement elementFromXMLString:cdataXML_ encoding:NSUTF8StringEncoding]; 49 | RXMLElement *rxml2 = [rxml copy]; 50 | STAssertEqualObjects(rxml2.text, @"thisiscdata", nil); 51 | } 52 | 53 | - (void)testTags { 54 | RXMLElement *rxml = [RXMLElement elementFromXMLString:simplifiedXML_ encoding:NSUTF8StringEncoding]; 55 | RXMLElement *rxml2 = [rxml copy]; 56 | __block NSInteger i = 0; 57 | 58 | [rxml2 iterate:@"*" usingBlock:^(RXMLElement *e) { 59 | if (i == 0) { 60 | STAssertEqualObjects(e.tag, @"square", nil); 61 | STAssertEqualObjects(e.text, @"Square", nil); 62 | } else if (i == 1) { 63 | STAssertEqualObjects(e.tag, @"triangle", nil); 64 | STAssertEqualObjects(e.text, @"Triangle", nil); 65 | } else if (i == 2) { 66 | STAssertEqualObjects(e.tag, @"circle", nil); 67 | STAssertEqualObjects(e.text, @"Circle", nil); 68 | } 69 | 70 | i++; 71 | }]; 72 | 73 | STAssertEquals(i, 3, nil); 74 | } 75 | 76 | - (void)testAttributes { 77 | RXMLElement *rxml = [RXMLElement elementFromXMLString:attributedXML_ encoding:NSUTF8StringEncoding]; 78 | RXMLElement *rxml2 = [rxml copy]; 79 | __block NSInteger i = 0; 80 | 81 | [rxml2 iterate:@"*" usingBlock:^(RXMLElement *e) { 82 | if (i == 0) { 83 | STAssertEqualObjects([e attribute:@"name"], @"Square", nil); 84 | } else if (i == 1) { 85 | STAssertEqualObjects([e attribute:@"name"], @"Triangle", nil); 86 | } else if (i == 2) { 87 | STAssertEqualObjects([e attribute:@"name"], @"Circle", nil); 88 | } 89 | 90 | i++; 91 | }]; 92 | 93 | STAssertEquals(i, 3, nil); 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /Tests/DeepChildrenTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DeepChildrenTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface DeepChildrenTests : SenTestCase { 12 | } 13 | 14 | @end 15 | 16 | 17 | 18 | @implementation DeepChildrenTests 19 | 20 | - (void)testQuery { 21 | RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"players.xml"]; 22 | __block NSInteger i = 0; 23 | 24 | // count the players 25 | RXMLElement *players = [rxml child:@"players"]; 26 | NSArray *children = [players children:@"player"]; 27 | 28 | [rxml iterateElements:children usingBlock: ^(RXMLElement *e) { 29 | i++; 30 | }]; 31 | 32 | STAssertEquals(i, 9, nil); 33 | } 34 | 35 | - (void)testDeepChildQuery { 36 | RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"players.xml"]; 37 | 38 | // count the players 39 | RXMLElement *coachingYears = [rxml child:@"players.coach.experience.years"]; 40 | 41 | STAssertEquals(coachingYears.textAsInt, 1, nil); 42 | } 43 | 44 | - (void)testDeepChildQueryWithWildcard { 45 | RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"players.xml"]; 46 | 47 | // count the players 48 | RXMLElement *coachingYears = [rxml child:@"players.coach.experience.teams.*"]; 49 | 50 | // first team returned 51 | STAssertEquals(coachingYears.textAsInt, 53, nil); 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Tests/DeepTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DeepTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface DeepTests : SenTestCase { 12 | } 13 | 14 | @end 15 | 16 | 17 | 18 | @implementation DeepTests 19 | 20 | - (void)testQuery { 21 | RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"players.xml"]; 22 | __block NSInteger i; 23 | 24 | // count the players 25 | i = 0; 26 | 27 | [rxml iterate:@"players.player" usingBlock: ^(RXMLElement *e) { 28 | i++; 29 | }]; 30 | 31 | STAssertEquals(i, 9, nil); 32 | 33 | // count the first player's name 34 | i = 0; 35 | 36 | [rxml iterate:@"players.player.name" usingBlock: ^(RXMLElement *e) { 37 | i++; 38 | }]; 39 | 40 | STAssertEquals(i, 1, nil); 41 | 42 | // count the coaches 43 | i = 0; 44 | 45 | [rxml iterate:@"players.coach" usingBlock: ^(RXMLElement *e) { 46 | i++; 47 | }]; 48 | 49 | STAssertEquals(i, 1, nil); 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Tests/ErrorTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ErrorTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface ErrorTests : SenTestCase { 12 | NSString *simplifiedXML_; 13 | NSString *badXML_; 14 | } 15 | 16 | @end 17 | 18 | 19 | 20 | @implementation ErrorTests 21 | 22 | - (void)setUp { 23 | simplifiedXML_ = @"\ 24 | \ 25 | Square\ 26 | Triangle\ 27 | Circle\ 28 | "; 29 | badXML_ = @"\ 20 | \ 22 | \ 23 | \ 24 | Minimal XHTML 1.1 Document\ 25 | \ 26 | \ 27 |

This is a minimal XHTML 1.1 document.

\ 28 | \ 29 | "; 30 | } 31 | 32 | - (void)testBasicXHTML { 33 | RXMLElement *html = [RXMLElement elementFromHTMLString:simpleHTML_ encoding:NSUTF8StringEncoding]; 34 | NSArray *atts = [html attributeNames]; 35 | STAssertEquals(atts.count, 2U, nil); 36 | 37 | NSArray* children = [html childrenWithRootXPath:@"//html/body/p"]; 38 | STAssertTrue([children count] > 0, nil); 39 | 40 | RXMLElement* child = [children objectAtIndex:0]; 41 | NSLog(@"content: %@", [child text]); 42 | STAssertEqualObjects([child text], @"This is a minimal XHTML 1.1 document.", nil); 43 | } 44 | 45 | -(void) testHtmlEntity { 46 | RXMLElement* html = [RXMLElement elementFromHTMLString:@"

Don't say "lazy"

" encoding:NSUTF8StringEncoding]; 47 | STAssertEqualObjects([html text], @"Don't say \"lazy\"", nil); 48 | } 49 | 50 | -(void) testFixBrokenHtml { 51 | RXMLElement* html = [RXMLElement elementFromHTMLString:@"

Test

Broken HTML" encoding:NSUTF8StringEncoding]; 52 | STAssertEqualObjects([html text], @"Test Broken HTML", nil); 53 | STAssertEqualObjects([html xml], @"

Test

Broken HTML", nil); 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Tests/SimpleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface SimpleTests : SenTestCase { 12 | NSString *simplifiedXML_; 13 | NSString *attributedXML_; 14 | NSString *interruptedTextXML_; 15 | NSString *cdataXML_; 16 | NSString *treeXML_; 17 | } 18 | 19 | @end 20 | 21 | 22 | 23 | @implementation SimpleTests 24 | 25 | - (void)setUp { 26 | simplifiedXML_ = @"\ 27 | \ 28 | Square\ 29 | Triangle\ 30 | Circle\ 31 | "; 32 | 33 | attributedXML_ = @"\ 34 | \ 35 | \ 36 | \ 37 | \ 38 | "; 39 | interruptedTextXML_ = @"thisisinterruptedtext"; 40 | cdataXML_ = @""; 41 | 42 | } 43 | 44 | - (void)testInterruptedText { 45 | RXMLElement *rxml = [RXMLElement elementFromXMLString:interruptedTextXML_ encoding:NSUTF8StringEncoding]; 46 | STAssertEqualObjects(rxml.text, @"thisisinterruptedtext", nil); 47 | } 48 | 49 | - (void)testCDataText { 50 | RXMLElement *rxml = [RXMLElement elementFromXMLString:cdataXML_ encoding:NSUTF8StringEncoding]; 51 | STAssertEqualObjects(rxml.text, @"thisiscdata", nil); 52 | } 53 | 54 | - (void)testTags { 55 | RXMLElement *rxml = [RXMLElement elementFromXMLString:simplifiedXML_ encoding:NSUTF8StringEncoding]; 56 | __block NSInteger i = 0; 57 | 58 | [rxml iterate:@"*" usingBlock:^(RXMLElement *e) { 59 | if (i == 0) { 60 | STAssertEqualObjects(e.tag, @"square", nil); 61 | STAssertEqualObjects(e.text, @"Square", nil); 62 | } else if (i == 1) { 63 | STAssertEqualObjects(e.tag, @"triangle", nil); 64 | STAssertEqualObjects(e.text, @"Triangle", nil); 65 | } else if (i == 2) { 66 | STAssertEqualObjects(e.tag, @"circle", nil); 67 | STAssertEqualObjects(e.text, @"Circle", nil); 68 | } 69 | 70 | i++; 71 | }]; 72 | 73 | STAssertEquals(i, 3, nil); 74 | } 75 | 76 | - (void)testAttributes { 77 | RXMLElement *rxml = [RXMLElement elementFromXMLString:attributedXML_ encoding:NSUTF8StringEncoding]; 78 | __block NSInteger i = 0; 79 | 80 | [rxml iterate:@"*" usingBlock:^(RXMLElement *e) { 81 | if (i == 0) { 82 | STAssertEqualObjects([e attribute:@"name"], @"Square", nil); 83 | } else if (i == 1) { 84 | STAssertEqualObjects([e attribute:@"name"], @"Triangle", nil); 85 | } else if (i == 2) { 86 | STAssertEqualObjects([e attribute:@"name"], @"Circle", nil); 87 | } 88 | 89 | i++; 90 | }]; 91 | 92 | STAssertEquals(i, 3, nil); 93 | } 94 | 95 | -(void) testInnerXml { 96 | treeXML_ = @"\ 97 | Circle\ 98 | TESTBlackdefault color\ 99 | "; 100 | 101 | RXMLElement *rxml = [RXMLElement elementFromXMLString:treeXML_ encoding:NSUTF8StringEncoding]; 102 | RXMLElement* shapes = [rxml child:@"shapes"]; 103 | STAssertEqualObjects(shapes.xml, @"Circle", nil); 104 | STAssertEqualObjects(shapes.innerXml, @"Circle", nil); 105 | 106 | RXMLElement* colors = [rxml child:@"colors"]; 107 | STAssertEqualObjects(colors.xml, @"TESTBlackdefault color", nil); 108 | STAssertEqualObjects(colors.innerXml, @"TESTBlackdefault color", nil); 109 | 110 | RXMLElement *cdata = [RXMLElement elementFromXMLString:cdataXML_ encoding:NSUTF8StringEncoding]; 111 | STAssertEqualObjects(cdata.xml, @"", nil); 112 | STAssertEqualObjects(cdata.innerXml, @"", nil); 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #import 4 | #import 5 | #endif 6 | -------------------------------------------------------------------------------- /Tests/TextConversionTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TextConversionTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface TextConversionTests : SenTestCase { 12 | NSString *simplifiedXML_; 13 | NSString *attributedXML_; 14 | } 15 | 16 | @end 17 | 18 | 19 | 20 | @implementation TextConversionTests 21 | 22 | - (void)setUp { 23 | simplifiedXML_ = @"\ 24 | \ 25 | \ 26 | 1\ 27 | Square\ 28 | \ 29 | \ 30 | 2.5\ 31 | Triangle\ 32 | \ 33 | "; 34 | 35 | attributedXML_ = @"\ 36 | \ 37 | \ 38 | Square\ 39 | \ 40 | \ 41 | Triangle\ 42 | \ 43 | "; 44 | } 45 | 46 | - (void)testIntTags { 47 | RXMLElement *rxml = [RXMLElement elementFromXMLString:simplifiedXML_ encoding:NSUTF8StringEncoding]; 48 | __block NSInteger i = 0; 49 | 50 | [rxml iterate:@"*" usingBlock:^(RXMLElement *e) { 51 | if (i == 0) { 52 | STAssertEquals([e child:@"id"].textAsInt, 1, nil); 53 | } else if (i == 1) { 54 | STAssertEqualsWithAccuracy([e child:@"id"].textAsDouble, 2.5, 0.01, nil); 55 | } 56 | 57 | i++; 58 | }]; 59 | } 60 | 61 | - (void)testIntAttributes { 62 | RXMLElement *rxml = [RXMLElement elementFromXMLString:attributedXML_ encoding:NSUTF8StringEncoding]; 63 | __block NSInteger i = 0; 64 | 65 | [rxml iterate:@"*" usingBlock:^(RXMLElement *e) { 66 | if (i == 0) { 67 | STAssertEquals([e attributeAsInt:@"id"], 1, nil); 68 | } else if (i == 1) { 69 | STAssertEqualsWithAccuracy([e attributeAsDouble:@"id"], 2.5, 0.01, nil); 70 | } else if (i == 2) { 71 | STAssertEquals([e attributeAsInt:@"id"], 3, nil); 72 | } 73 | 74 | i++; 75 | }]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Tests/WildcardTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WildcardTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 9/24/11. 6 | // Copyright (c) 2011 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface WildcardTests : SenTestCase { 12 | } 13 | 14 | @end 15 | 16 | 17 | 18 | @implementation WildcardTests 19 | 20 | - (void)testEndingWildcard { 21 | RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"players.xml"]; 22 | __block NSInteger i; 23 | 24 | // count the players and coaches 25 | i = 0; 26 | 27 | [rxml iterate:@"players.*" usingBlock: ^(RXMLElement *e) { 28 | i++; 29 | }]; 30 | 31 | STAssertEquals(i, 10, nil); 32 | } 33 | 34 | - (void)testMidstreamWildcard { 35 | RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"players.xml"]; 36 | __block NSInteger i; 37 | 38 | // count the tags that have a name 39 | i = 0; 40 | 41 | [rxml iterate:@"players.*.name" usingBlock: ^(RXMLElement *e) { 42 | i++; 43 | }]; 44 | 45 | // STAssertEquals(i, 10, nil); 46 | 47 | // count the tags that have a position 48 | i = 0; 49 | 50 | [rxml iterate:@"players.*.position" usingBlock: ^(RXMLElement *e) { 51 | i++; 52 | }]; 53 | 54 | // STAssertEquals(i, 9, nil); 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Tests/XPathTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // XPathTests.m 3 | // RaptureXML 4 | // 5 | // Created by John Blanco on 4/14/12. 6 | // Copyright (c) 2012 Rapture In Venice. All rights reserved. 7 | // 8 | 9 | #import "RXMLElement.h" 10 | 11 | @interface XPathTests : SenTestCase { 12 | NSString *simplifiedXML_; 13 | NSString *attributedXML_; 14 | NSString *interruptedTextXML_; 15 | NSString *cdataXML_; 16 | } 17 | 18 | @end 19 | 20 | 21 | 22 | @implementation XPathTests 23 | 24 | - (void)setUp { 25 | simplifiedXML_ = @"\ 26 | \ 27 | Square\ 28 | Triangle\ 29 | Circle\ 30 | "; 31 | 32 | attributedXML_ = @"\ 33 | \ 34 | \ 35 | \ 36 | \ 37 | "; 38 | interruptedTextXML_ = @"thisisinterruptedtext"; 39 | cdataXML_ = @""; 40 | } 41 | 42 | - (void)testBasicPath { 43 | __block NSInteger i = 0; 44 | 45 | RXMLElement *rxml = [RXMLElement elementFromXMLString:simplifiedXML_ encoding:NSUTF8StringEncoding]; 46 | 47 | [rxml iterateWithRootXPath:@"//circle" usingBlock:^(RXMLElement *element) { 48 | STAssertEqualObjects(element.text, @"Circle", nil); 49 | i++; 50 | }]; 51 | 52 | STAssertEquals(i, 1, nil); 53 | } 54 | 55 | - (void)testAttributePath { 56 | __block NSInteger i = 0; 57 | 58 | RXMLElement *rxml = [RXMLElement elementFromXMLString:attributedXML_ encoding:NSUTF8StringEncoding]; 59 | 60 | [rxml iterateWithRootXPath:@"//circle[@name='Circle']" usingBlock:^(RXMLElement *element) { 61 | STAssertEqualObjects([element attribute:@"name"], @"Circle", nil); 62 | i++; 63 | }]; 64 | 65 | STAssertEquals(i, 1, nil); 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Tests/players.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Terry Collins 5 | 6 | 1 7 | 8 | 53 9 | 12 10 | 11 | 12 | 13 | 14 | 15 | Jose Reyes 16 | SS 17 | 18 | 19 | 20 | Angel Pagan 21 | CF 22 | 23 | 24 | 25 | David Wright 26 | 3B 27 | 28 | 29 | 30 | Ike Davis 31 | 1B 32 | 33 | 34 | 35 | Lucas Duda 36 | RF 37 | 38 | 39 | 40 | Jason Bay 41 | LF 42 | 43 | 44 | 45 | Josh Thole 46 | C 47 | 48 | 49 | 50 | Justin Turner 51 | 2B 52 | 53 | 54 | 55 | R.A. Dickey 56 | SP 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaBlanc/RaptureXML/9e027daca532bb496437da3d2bf030c8f9251c67/icon.png --------------------------------------------------------------------------------