Upgrade to Pro — share decks privately, control downloads, hide ads and more …

iOSDC令和時代のXML処理を考える

Avatar for coe coe
September 10, 2022

 iOSDC令和時代のXML処理を考える

令和時代のXML処理を考える 〜もしあなたが巨大なXMLと相見える(あいまみえる)ことになったら〜 iOSDC Japan 2022

Avatar for coe

coe

September 10, 2022
Tweet

More Decks by coe

Other Decks in Technology

Transcript

  1. 9*# 9.-*OUFSGBDF#VJMEFS <?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch"

    propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX"> <device id="retina5_9" orientation="portrait" appearance="light"/> <dependencies> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> <!--Top View Controller--> <scene sceneID="s0d-6b-0kx"> <objects> <viewController id="Y6W-OH-hqX" customClass="TopViewController" customModule="WinkCamera" customModuleProvider="target" sceneMemberID="viewController"> <view key="view" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="5EZ-qb-Rvc" customClass="PreviewView" customModule="WinkCamera" customModuleProvider="target"> <rect key="frame" x="0.0" y="0.0" width="375" height="812"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <viewLayoutGuide key="safeArea" id="Yhj-UR-jNr"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/> </view> <connections> <outlet property="previewView" destination="5EZ-qb-Rvc" id="eQc-tb-WN6"/> <outlet property="winkControl" destination="eOh-BF-nHF" id="ueK-OC-EJQ"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> <customObject id="eOh-BF-nHF" customClass="WinkControl" customModule="WinkCamera" customModuleProvider="target"> <connections> <action selector="takePhoto:" destination="CVf-dU-zam" eventType="valueChanged" id="jmL-r1-JhV"/> </connections> </customObject> <exit id="CVf-dU-zam" userLabel="Exit" sceneMemberID="exit"/> </objects> <point key="canvasLocation" x="35" y="104"/> </scene> </scenes> <resources> <systemColor name="systemBackgroundColor"> <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> </systemColor> </resources> </document> •
  2. %0.

  3. ࣮ࡍʹ࢖ͬͯΈΔ 9.-%PDVNFOU w 9.-%PDVNFOUΛ࢖ͬͯ ͷ9.-಺༰දࣔ let data = NSDataAsset(name: "Rss")!.data

    let doc = try! XMLDocument(data: data) text = doc.rootElement()? .elements(forName: "channel").first? .elements(forName: "title").first? .stringValue ?? "" print(text) // RSSͷλΠτϧදࣔ
  4. ࣮ࡍʹ࢖ͬͯΈΔ 9.-%PDVNFOU w 9.-%PDVNFOUΛ࢖ͬͯ ͷ9.-಺༰දࣔ w 9.-%PDVNFOU͕J04 Ͱ͸ϏϧυΤϥʔ let data

    = NSDataAsset(name: "Rss")!.data // Cannot find 'XMLDocument' in scope let doc = try! XMLDocument(data: data) text = doc.rootElement()? .elements(forName: "channel").first? .elements(forName: "title").first? .stringValue ?? "" print(text) // RSSͷλΠτϧදࣔ
  5. ࣮ࡍʹ࢖ͬͯΈΔ 9.-%PDVNFOU w 9.-%PDVNFOUΛ࢖ͬͯ ͷ9.-಺༰දࣔ w 9.-%PDVNFOU͕J04 Ͱ͸ϏϧυΤϥʔ w 9.-%PDVNFOU͸

    NBD04ͷΈͷରԠ let data = NSDataAsset(name: "Rss")!.data #if os(macOS) let doc = try! XMLDocument(data: data) text = doc.rootElement()? .elements(forName: "channel").first? .elements(forName: "title").first? .stringValue ?? "" #endif print(text) // RSSͷλΠτϧදࣔ
  6. MJCYNM 0CKFDUJWF$ NSURL* url; auto fileUrl = [[url absoluteString] UTF8String];

    auto document = xmlReadFile(fileUrl, NULL, XML_PARSE_HUGE); auto cur = xmlDocGetRootElement(document); if (xmlStrcmp(cur->name, (xmlChar *)"HealthData") != 0) { return @""; } cur = cur->children; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar*)”ExportDate"))) { auto value = xmlGetProp(cur, (xmlChar *)"value"); auto valueString = [NSString stringWithCString:(char*)value encoding:NSUTF8StringEncoding]; return valueString; // xmlͷग़ྗ೔෇औಘ } cur = cur->next; } return @"";
  7. MJCYNMʹΑΔಡΈࠐΈ ϔϧεέΞσʔλͷಡΈࠐΈ w ϔϧεέΞσʔλͷYNMϑ ΝΠϧΛಡΈࠐΈ w (͋Γ·͢ let url =

    Bundle.main.url(forResource: "export", withExtension: "xml")! let start = Date() // ಺෦ͰlibxmlΛ࢖ͬͯಡΈࠐΈ let obj = MyObject(url: url) text = obj.readText() let end = Date() print(start.distance(to: end)) print(text)
  8. MJCYNMʹΑΔಡΈࠐΈ ϔϧεέΞσʔλͷಡΈࠐΈ w ϔϧεέΞσʔλͷYNMϑ ΝΠϧΛಡΈࠐΈ w (͋Γ·͢ w ಡΈࠐΈ͢Δͷʹ ඵ͔͔Δ

    let url = Bundle.main.url(forResource: "export", withExtension: "xml")! let start = Date() // ಺෦ͰlibxmlΛ࢖ͬͯಡΈࠐΈ let obj = MyObject(url: url) text = obj.readText() let end = Date() print(start.distance(to: end)) //←35ඵ print(text)
  9. w 4"9 &WFOU%SJWFO9.-  w 9.-Λઌ಄͔ΒಡΈࠐΈɺಛ௃఺͕ݟ͔ͭΔͨͼʹΠϕϯτͱͯ͠ฦ͢ w 9.-1BSTFS w %0.

    5SFF#BTFE9.-  w 9.-ΛશͯಡΈࠐΜͰΦϒδΣΫτԽ͠ɺΦϒδΣΫτ͔Βඞཁͳσʔ λʹΞΫηε͢Δ w େྔͷϦιʔε͕ඞཁʹͳΔ w 9.-%PDVNFOU .BDͷΈ 9.-ॲཧͷछྨ Ұൠతͳ9.-ͷղੳ
  10. 9.-1BSTFSʹΑΔಡΈࠐΈ ϔϧεέΞσʔλͷಡΈࠐΈ w ϔϧεέΞσʔλͷYNMϑ ΝΠϧΛಡΈࠐΈ w (ͷYNMϑΝΠϧ let url =

    Bundle.main.url(forResource: "export", withExtension: "xml")! let start = Date() let parser = XMLParser(contentsOf: url)! // ඞཁͳ஋Λऔಘ͢ΔͨΊͷॲཧΛdelegateʹ࣮૷ parser.delegate = self parser.parse() let end = Date() print(text) print(start.distance(to: end))
  11. 9.-1BSTFSʹΑΔಡΈࠐΈ ϔϧεέΞσʔλͷಡΈࠐΈ w ϔϧεέΞσʔλͷYNMϑ ΝΠϧΛಡΈࠐΈ w (ͷYNMϑΝΠϧ w ඵͰඞཁͳςΩε τ͕औಘͰ͖Δ

    w ΠϕϯτΛ؂ࢹ͠ɺඞ ཁͳσʔλΛऔಘ͠ऴ ͑ͨΒૣظऴྃ͢Δ let url = Bundle.main.url(forResource: "export", withExtension: "xml")! let start = Date() let parser = XMLParser(contentsOf: url)! // ඞཁͳ஋Λऔಘ͢ΔͨΊͷॲཧΛdelegateʹ࣮૷ parser.delegate = self parser.parse() let end = Date() print(text) print(start.distance(to: end)) // ← 0.2ඵ
  12. 9.-1BSTFSʹΑΔಡΈࠐΈ ϔϧεέΞσʔλͷಡΈࠐΈ w ϔϧεέΞσʔλͷYNMϑ ΝΠϧΛಡΈࠐΈ w (ͷYNMϑΝΠϧ w ඵͰඞཁͳςΩε τ͕औಘͰ͖Δ

    w ΠϕϯτΛ؂ࢹ͠ɺඞ ཁͳσʔλΛऔಘ͠ऴ ͑ͨΒૣظऴྃ͢Δ // MARK: - XMLParserDelegate func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { // σʔλऔಘʹඞཁͳॲཧΛߦ͏ } func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { // ඞཁͳσʔλ͕औಘͰ͖ͨΒɺXMLParserΛૣظऴྃ parser.abortParsing() }
  13. 9.-1BSTFS खॱ w 9.-1BSTFSͷॳظԽ w %BUB w *OQVU4USFBN w 63-

    w 9.-1BSTFS%FMFHBUFΛઃఆͯ͠ ΠϕϯτΛड͚औΕΔΑ͏ʹ͢Δ w 9.-1BSTFSQBSTF Λ࣮ߦͯ͠ ֤छΠϕϯτΛEFMFHBUFͰॲཧ
  14. 9.-1BSTFS खॱ w 9.-1BSTFSͷॳظԽ w %BUB w *OQVU4USFBN w 63-

    w 9.-1BSTFS%FMFHBUFΛઃఆͯ͠ ΠϕϯτΛड͚औΕΔΑ͏ʹ͢Δ w 9.-1BSTFSQBSTF Λ࣮ߦͯ͠ ֤छΠϕϯτΛEFMFHBUFͰॲཧ let parser = XMLParser(contentsOf: url)! // ॳظԽ parser.delegate = self //delegateઃఆ parser.parse() // ॲཧ։࢝
  15. w 9.-1BSTFS%FMFHBUFQBSTFS @EJE4UBSU&MFNFOUOBNFTQBDF63*RV BMJ fi FE/BNFBUUSJCVUFT  w ཁૉ໊ͷ։͕࢝ݟ͔ͭͬͨ৔߹ʹݺͼग़͞ΕΔ w

    9.-1BSTFS%FMFHBUFQBSTFS @GPVOE$IBSBDUFST w ಺༰͕ݟ͔ͭͬͨ৔߹ʹݺͼग़͞ΕΔ w ҰճͰ͸಺༰͕શͯಡΈऔΕͣɺෳ਺ճݺ͹ΕΔ৔߹΋͋Δ w 9.-1BSTFS%FMFHBUFQBSTFS @EJE&OE&MFNFOUOBNFTQBDF63*RVBM J fi FE/BNF w ཁૉ໊ͷऴ͕ྃݟ͔ͭͬͨ৔߹ʹݺͼग़͞ΕΔ Α͘࢖͏GVOD 9.-1BSTFS%FMFHBUF
  16. ಺༰ͷऔಘ func parser(_ parser: XMLParser, foundCharacters string: String) { print(string)

    // ԕ͘ͰςϨϏͷిݯ͕ೖͬͨ͜ͱ͕Θ͔Δ } 9.-1BSTFS%FMFHBUF
  17. <ϓϩϑΟʔϧ> <໊લ>೔޲ڧ</໊લ> <ॴଐ>גࣜձࣾAmazia</ॴଐ> <աڈͷiOSDC> <λΠτϧ year="2019">BLEͰiOS/AndroidؒͰͦͦ͜͜େ͖ͳαΠζͷσʔλ௨৴Λ࣮ݱ͢Δ (L2CAP΋͋ΔΑ)</λΠτϧ> <λΠτϧ year="2020">ৄղStoryboard</λΠτϧ> <λΠτϧ

    year="2020">͋ͳͨͷ஌Βͳ͍࿈བྷઌͷੈք</λΠτϧ> <λΠτϧ year="2021">όοΫάϥ΢ϯυͰΞϓϦ͕Ωϧ͞Εͯ΋ා͘ͳ͍ʂΞϓϦͷঢ়ଶΛݩʹ໭͢ϦετΞػೳͷશͯ</λΠτϧ> </աڈͷiOSDC> <޷͖ͳ3DO>REAL</޷͖ͳ3DO> <ಛٕ>ԕ͘ͰςϨϏͷిݯ͕ೖͬͨ͜ͱ͕Θ͔Δ</ಛٕ> </ϓϩϑΟʔϧ>
  18. ಺༰ͷऔಘ func parser(_ parser: XMLParser, foundCharacters string: String) { print(string)

    // ೔޲ڧ // גࣜձࣾAmazia // BLEͰiOS/AndroidؒͰͦͦ͜͜େ͖ͳαΠζͷσʔλ௨৴Λ࣮ݱ͢Δ (L2CAP΋͋ΔΑ) // ৄղStoryboard // ͋ͳͨͷ஌Βͳ͍࿈བྷઌͷੈք // όοΫάϥ΢ϯυͰΞϓϦ͕Ωϧ͞Εͯ΋ා͘ͳ͍ʂΞϓϦͷঢ়ଶΛݩʹ໭͢ϦετΞػೳͷશͯ // REAL // ԕ͘ͰςϨϏͷిݯ͕ೖͬͨ͜ͱ͕Θ͔Δ } 9.-1BSTFS%FMFHBUF
  19. var isName = false func parser(_ parser: XMLParser, didStartElement elementName:

    String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { // ݱࡏղੳதͷλάΛ൑ఆ if elementName == "໊લ" { isName = true } } func parser(_ parser: XMLParser, foundCharacters string: String) { if isName { text.append(string) } } func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { // ղੳதϑϥάΛOFF if elementName == "໊લ" { isName = false } } 9.-1BSTFS%FMFHBUF ໊લΛऔಘ
  20. public func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?,

    qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { let child = ElementParser(parser: parser, elementName: elementName, attributeDict: attributeDict, parent: self, parentElement: element) childParser = child parser.delegate = child } 9.-1BSTFSͰ%0. 6TJOH.VMUJQMF%FMFHBUFT ։࢝λά͕ݟ͔ͭΔͨͼʹ৽ͨʹΦϒδΣΫτΛ࡞੒͠ɺEFMFHBUFͷର৅Λ੾Γସ͑Δ
  21. public func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?,

    qualifiedName qName: String?) { parentParser?.addChild(element) parser.delegate = parentParser } private func addChild(_ child: Element) { element.addElement(child) } 9.-1BSTFSͰ%0. 6TJOH.VMUJQMF%FMFHBUFT λά͕ऴྃͨ͠Β਌ΤϨϝϯτʹ௥Ճ
  22. let parser = ElementParser() let xmlParser = XMLParser(data: rss2XmlData) let

    rss2document: Element = parser.getDocument(from: xmlParser) 9.-1BSTFSͰ%0. 6TJOH.VMUJQMF%FMFHBUFT 344ͷ%0.Λऔಘ
  23. let parser = ElementParser() let xmlParser = XMLParser(data: rss2XmlData) let

    rss2document: Element = parser.getDocument(from: xmlParser) STTWFSTJPO DIBOOFM UJUMFχϡʔεɾτϐοΫεUJUMF  JUFN UJUMF5TVZPTIJIZVHBɺϝΨωΛ৽ௐUJUMF  JUFN DIBOOFM STT 9.-1BSTFSͰ%0. 6TJOH.VMUJQMF%FMFHBUFT STTEPDVNFOU͔ΒUJUMFΛऔಘ͢Δʹ͸ʁ
  24. @dynamicMemberLookup public class Element { private var _elements: [String: [Element]]

    public subscript(dynamicMember member: String) -> Element? { return _elements[member]?[0] } 6TJOH.VMUJQMF%FMFHBUFT !EZOBNJD.FNCFS-PPLVQ
  25. let parser = ElementParser() let xmlParser = XMLParser(data: rss2XmlData) let

    rss2document: Element = parser.getDocument(from: xmlParser) 6TJOH.VMUJQMF%FMFHBUFT !EZOBNJD.FNCFS-PPLVQ
  26. let parser = ElementParser() let xmlParser = XMLParser(data: rss2XmlData) let

    rss2document: Element = parser.getDocument(from: xmlParser) // χϡʔεɾτϐοΫε let channelTitle = rss2document.rss?.channel?.title?.getStringValue() // Tsuyoshi hyugaɺϝΨωΛ৽ௐ let itemTitle = rss2document.rss?.channel?.item?[0]?.title?.getStringValue() 6TJOH.VMUJQMF%FMFHBUFT !EZOBNJD.FNCFS-PPLVQ STTWFSTJPO DIBOOFM UJUMFχϡʔεɾτϐοΫεUJUMF  JUFN UJUMF5TVZPTIJIZVHBɺϝΨωΛ৽ௐUJUMF  JUFN DIBOOFM STT
  27. let atomData = atomXml.data(using: .utf8)! let parser = ElementParser() let

    xmlParser = XMLParser(data: atomData) let document: Element = parser.getDocument(from: xmlParser) let channelTitle = document.feed?.title?.getStringValue() let itemTitle = document.feed?.entry?[2]?.title?.getStringValue() document.feed?.entry?.getArrayValue()?.forEach({ _ in // ԿΒ͔ͷॲཧ }) 6TJOH.VMUJQMF%FMFHBUFT !EZOBNJD.FNCFS-PPLVQ "UPNGFFE
  28. let data = profileXml.data(using: .utf8)! let parser = ElementParser() let

    xmlParser = XMLParser(data: data) let document: Element = parser.getDocument(from: xmlParser) document.ϓϩϑΟʔϧ?.໊લ?.getStringValue() // ೔޲ڧ document.ϓϩϑΟʔϧ?.޷͖ͳ3DO?.getStringValue() // REAL document.ϓϩϑΟʔϧ?.ओͳ࣮੷?.getStringValue() // nil 6TJOH.VMUJQMF%FMFHBUFT !EZOBNJD.FNCFS-PPLVQ ϓϩϑΟʔϧ
  29. ໊લۭؒ 344 SEG3%'YNMOTIUUQQVSMPSHSTTYNMOTSEGIUUQXXXXPSHSEGTZOUBYOTYNMOTEDIUUQQVSMPSH EDFMFNFOUTYNMOTNOIUUQVTFGVMJODDPNSTTNBOJGFTUYNMMBOHKB DIBOOFM UJUMF೔هUJUMF ʜ DIBOOFM ʜ JUFNSEGBCPVUIUUQTFYBNQMFBSUJDMF

    UJUMFλΠτϧUJUMF MJOLIUUQTHJIZPKQFYBNQMFBSUJDMFMJOL EFTDSJQUJPOίϯςϯπͷઆ໌Ͱ͢EFTDSJQUJPO EDEBUF5 EDEBUF EDTVCKFDUϗοτϥΠϯEDTVCKFDU EDDSFBUPSUTVZPTIJIZVHBEDDSFBUPS JUFN SEG3%'
  30. ໊લۭؒ 344 SEG3%'YNMOTIUUQQVSMPSHSTTYNMOTSEGIUUQXXXXPSHSEGTZOUBYOTYNMOTEDIUUQ QVSMPSHEDFMFNFOUTYNMOTNOIUUQVTFGVMJODDPNSTTNBOJGFTUYNMMBOHKB DIBOOFM UJUMF೔هUJUMF ʜ DIBOOFM ʜ JUFNSEGBCPVUIUUQTFYBNQMFBSUJDMF

    UJUMFλΠτϧUJUMF MJOLIUUQTHJIZPKQFYBNQMFBSUJDMFMJOL EFTDSJQUJPOίϯςϯπͷઆ໌Ͱ͢EFTDSJQUJPO EDEBUF5 EDEBUF EDTVCKFDUϗοτϥΠϯEDTVCKFDU EDDSFBUPSUTVZPTIJIZVHBEDDSFBUPS JUFN SEG3%' EDͷ໊લۭؒఆٛ
  31. ໊લۭؒ 344 SEG3%'YNMOTIUUQQVSMPSHSTTYNMOTSEGIUUQXXXXPSHSEGTZOUBYOTYNMOTEDIUUQ QVSMPSHEDFMFNFOUTYNMOTNOIUUQVTFGVMJODDPNSTTNBOJGFTUYNMMBOHKB DIBOOFM UJUMF೔هUJUMF ʜ DIBOOFM ʜ JUFNSEGBCPVUIUUQTFYBNQMFBSUJDMF

    UJUMFλΠτϧUJUMF MJOLIUUQTHJIZPKQFYBNQMFBSUJDMFMJOL EFTDSJQUJPOίϯςϯπͷઆ໌Ͱ͢EFTDSJQUJPO EDEBUF5 EDEBUF EDTVCKFDUϗοτϥΠϯEDTVCKFDU EDDSFBUPSUTVZPTIJIZVHBEDDSFBUPS JUFN SEG3%' ໊લۭؒ63-EDʹଐ͢Δ
  32. w σϑΥϧτ͸GBMTF w USVFʹ͢Δͱɺ9.-1BSTFS%FMFHBUFͷҎԼͷGVODͷಈ࡞͕มΘ Δ w QBSTFS @EJE4UBSU&MFNFOUOBNFTQBDF63*RVBMJ fi FE/B

    NFBUUSJCVUFT w QBSTFS @EJE&OE&MFNFOUOBNFTQBDF63*RVBMJ fi FE/B NF TIPVME1SPDFTT/BNFTQBDFT ໊લۭؒ
  33. TIPVME1SPDFTT/BNFTQBDFT ໊લۭؒॲཧ '"-4& %FGBVMU 536& FMFNFOU/BNF EDEBUF EBUF OBNFTQBDF63* OJM

    IUUQQVSMPSHEDFMFNFOUT R/BNF OJM EDEBUF SEG3%'YNMOTIUUQQVSMPSHSTTYNMOTSEGIUUQXXXXPSHSEGTZOUBYOTYNMOTEDIUUQ QVSMPSHEDFMFNFOUTYNMOTNOIUUQVTFGVMJODDPNSTTNBOJGFTUYNMMBOHKB DIBOOFM UJUMF೔هUJUMF ʜ DIBOOFM ʜ JUFNSEGBCPVUIUUQTFYBNQMFBSUJDMF UJUMFλΠτϧUJUMF MJOLIUUQTHJIZPKQFYBNQMFBSUJDMFMJOL EFTDSJQUJPOίϯςϯπͷઆ໌Ͱ͢EFTDSJQUJPO EDEBUF5 EDEBUF EDTVCKFDUϗοτϥΠϯEDTVCKFDU EDDSFBUPSUTVZPTIJIZVHBEDDSFBUPS JUFN SEG3%'
  34. w σϑΥϧτ͸GBMTF w USVFʹ͢Δͱɺ9.-1BSTFS%FMFHBUFͰ৽ͨͳϝιου͕ίʔϧ ͞ΕΔΑ͏ʹͳΔ w QBSTFS @EJE4UBSU.BQQJOH1SF fi YUP63*

    w QBSTFS @EJE&OE.BQQJOH1SF fi Y  w ໊લۭؒఆٛΛಡΈࠐΜͩͱ͖ʹݺ͹ΕΔ TIPVME3FQPSU/BNFTQBDF1SF fi YFT ໊લۭؒ
  35. %5%

  36. %5%

  37. ϔϧεέΞͷ9.-%5%ൈਮ %5% %0$5:1&)FBMUI%BUB< )FBMUI,JU&YQPSU7FSTJPO &-&.&/5)FBMUI%BUB &YQPSU%BUF .F 3FDPSEc$PSSFMBUJPOc8PSLPVUc"DUJWJUZ4VNNBSZc$MJOJDBM3FDPSE  "55-*45)FBMUI%BUB

    MPDBMF$%"5"3&26*3&%  &-&.&/5&YQPSU%BUF&.15: "55-*45&YQPSU%BUF WBMVF$%"5"3&26*3&%  &-&.&/5.F&.15: "55-*45.F ),$IBSBDUFSJTUJD5ZQF*EFOUJ fi FS%BUF0G#JSUI$%"5"3&26*3&% ),$IBSBDUFSJTUJD5ZQF*EFOUJ fi FS#JPMPHJDBM4FY$%"5"3&26*3&% ),$IBSBDUFSJTUJD5ZQF*EFOUJ fi FS#MPPE5ZQF$%"5"3&26*3&% ),$IBSBDUFSJTUJD5ZQF*EFOUJ fi FS'JU[QBUSJDL4LJO5ZQF$%"5"3&26*3&%   >
  38. &-&.&/5"55-*45 %5% &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU  "55-*453FDPSE UZQF$%"5"3&26*3&% VOJU$%"5"*.1-*&% WBMVF$%"5"*.1-*&% TPVSDF/BNF$%"5"3&26*3&%

    TPVSDF7FSTJPO$%"5"*.1-*&% EFWJDF$%"5"*.1-*&% DSFBUJPO%BUF$%"5"*.1-*&% TUBSU%BUF$%"5"3&26*3&% FOE%BUF$%"5"3&26*3&% 
  39. &-&.&/5"55-*45 %5% &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU  "55-*453FDPSE UZQF$%"5"3&26*3&% VOJU$%"5"*.1-*&% WBMVF$%"5"*.1-*&% TPVSDF/BNF$%"5"3&26*3&%

    TPVSDF7FSTJPO$%"5"*.1-*&% EFWJDF$%"5"*.1-*&% DSFBUJPO%BUF$%"5"*.1-*&% TUBSU%BUF$%"5"3&26*3&% FOE%BUF$%"5"3&26*3&%  3FDPSEUZQF),2VBOUJUZ5ZQF*EFOUJ fi FS#MPPE(MVDPTFTPVSDF/BNFϔϧεέΞTPVSDF7FSTJPOVOJUNHE- DSFBUJPO%BUF TUBSU%BUF FOE%BUF WBMVF .FUBEBUB&OUSZLFZ),8BT6TFS&OUFSFEWBMVF 3FDPSE
  40. &-&.&/5 %5% &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU  "55-*453FDPSE UZQF$%"5"3&26*3&% VOJU$%"5"*.1-*&% WBMVF$%"5"*.1-*&% TPVSDF/BNF$%"5"3&26*3&%

    TPVSDF7FSTJPO$%"5"*.1-*&% EFWJDF$%"5"*.1-*&% DSFBUJPO%BUF$%"5"*.1-*&% TUBSU%BUF$%"5"3&26*3&% FOE%BUF$%"5"3&26*3&%  3FDPSEUZQF),2VBOUJUZ5ZQF*EFOUJ fi FS#MPPE(MVDPTFTPVSDF/BNFϔϧεέΞTPVSDF7FSTJPOVOJUNHE- DSFBUJPO%BUF TUBSU%BUF FOE%BUF WBMVF .FUBEBUB&OUSZLFZ),8BT6TFS&OUFSFEWBMVF 3FDPSE
  41. "55-*45 %5% &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU  "55-*453FDPSE UZQF$%"5"3&26*3&% VOJU$%"5"*.1-*&% WBMVF$%"5"*.1-*&% TPVSDF/BNF$%"5"3&26*3&%

    TPVSDF7FSTJPO$%"5"*.1-*&% EFWJDF$%"5"*.1-*&% DSFBUJPO%BUF$%"5"*.1-*&% TUBSU%BUF$%"5"3&26*3&% FOE%BUF$%"5"3&26*3&%  3FDPSEUZQF),2VBOUJUZ5ZQF*EFOUJ fi FS#MPPE(MVDPTFTPVSDF/BNFϔϧεέΞTPVSDF7FSTJPOVOJUNH E-DSFBUJPO%BUF TUBSU%BUF FOE%BUF  WBMVF .FUBEBUB&OUSZLFZ),8BT6TFS&OUFSFEWBMVF 3FDPSE
  42. optional func parser( _ parser: XMLParser, foundElementDeclarationWithName elementName: String, model:

    String ) &-&.&/5ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE&MFNFOU%FDMBSBUJPO8JUI/BNFNPEFM parser An NSXMLParser object parsing XML. elementName A string that is the name of an element. model A string that specifies a model for elementName.
  43. &-&.&/5ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE&MFNFOU%FDMBSBUJPO8JUI/BNFNPEFM parser An NSXMLParser object parsing XML. elementName

    A string that is the name of an element. model A string that specifies a model for elementName. &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU 
  44. &-&.&/5ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE&MFNFOU%FDMBSBUJPO8JUI/BNFNPEFM parser An NSXMLParser object parsing XML. elementName

    A string that is the name of an element. model A string that specifies a model for elementName. &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU 
  45. &-&.&/5ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE&MFNFOU%FDMBSBUJPO8JUI/BNFNPEFM parser An NSXMLParser object parsing XML. elementName

    A string that is the name of an element. model A string that specifies a model for elementName. &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU 
  46. optional func parser( _ parser: XMLParser, foundElementDeclarationWithName elementName: String, model:

    String ) &-&.&/5ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE&MFNFOU%FDMBSBUJPO8JUI/BNFNPEFM &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU  ༧૝ FMFNFOU/BNF 3FDPSE NPEFM .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU
  47. optional func parser( _ parser: XMLParser, foundElementDeclarationWithName elementName: String, model:

    String ) &-&.&/5ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE&MFNFOU%FDMBSBUJPO8JUI/BNFNPEFM &-&.&/53FDPSE .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU  ༧૝ ࣮ࡍ FMFNFOU/BNF 3FDPSE 3FDPSE NPEFM .FUBEBUB&OUSZc)FBSU3BUF7BSJBCJMJUZ.FUBEBUB-JTU ۭจࣈ
  48. optional func parser( _ parser: XMLParser, foundAttributeDeclarationWithName attributeName: String, forElement

    elementName: String, type: String?, defaultValue: String? ) "55-*45ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE"UUSJCVUF%FDMBSBUJPO8JUI/BNFGPS&MFNFOUUZQFEFGBVMU7B MVF  parser An NSXMLParser object parsing XML. attributeName A string that is the name of an attribute. elementName A string that is the name of an element that has the attribute attributeName. type A string, such as "ENTITY", "NOTATION", or "ID", that indicates the type of the attribute. defaultValue A string that specifies the default value of the attribute.
  49. "55-*45ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE"UUSJCVUF%FDMBSBUJPO8JUI/BNFGPS&MFNFOUUZQFEFGBVMU7B MVF  parser An NSXMLParser object parsing

    XML. attributeName A string that is the name of an attribute. elementName A string that is the name of an element that has the attribute attributeName. type A string, such as "ENTITY", "NOTATION", or "ID", that indicates the type of the attribute. defaultValue A string that specifies the default value of the attribute. "55-*45TRVBSFXJEUI$%"5"
  50. "55-*45ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE"UUSJCVUF%FDMBSBUJPO8JUI/BNFGPS&MFNFOUUZQFEFGBVMU7B MVF  parser An NSXMLParser object parsing

    XML. attributeName A string that is the name of an attribute. elementName A string that is the name of an element that has the attribute attributeName. type A string, such as "ENTITY", "NOTATION", or "ID", that indicates the type of the attribute. defaultValue A string that specifies the default value of the attribute. "55-*45TRVBSFXJEUI$%"5" ͭͷ஋͕ͦΕͧΕͷύϥϝʔλʹͳ͍ͬͯΔ
  51. "55-*45ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE"UUSJCVUF%FDMBSBUJPO8JUI/BNFGPS&MFNFOUUZQFEFGBVMU7B MVF  ༧૝ BUUSJCVUF/BNF XJEUI FMFNFOU/BNF TRVBSF

    UZQF $%"5" EFGBVMU7BMVF  optional func parser( _ parser: XMLParser, foundAttributeDeclarationWithName attributeName: String, forElement elementName: String, type: String?, defaultValue: String? ) "55-*45TRVBSFXJEUI$%"5"
  52. "55-*45ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE"UUSJCVUF%FDMBSBUJPO8JUI/BNFGPS&MFNFOUUZQFEFGBVMU7B MVF  ༧૝ ݁Ռ BUUSJCVUF/BNF XJEUI XJEUI

    FMFNFOU/BNF TRVBSF TRVBSF UZQF $%"5" ۭจࣈ EFGBVMU7BMVF   optional func parser( _ parser: XMLParser, foundAttributeDeclarationWithName attributeName: String, forElement elementName: String, type: String?, defaultValue: String? ) "55-*45TRVBSFXJEUI$%"5"
  53. "55-*45ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE"UUSJCVUF%FDMBSBUJPO8JUI/BNFGPS&MFNFOUUZQFEFGBVMU7B MVF  ༧૝ ࣮ࡍ BUUSJCVUF/BNF XJEUI XJEUI

    FMFNFOU/BNF TRVBSF TRVBSF UZQF $%"5" ۭจࣈ EFGBVMU7BMVF 3&26*3&% OJM optional func parser( _ parser: XMLParser, foundAttributeDeclarationWithName attributeName: String, forElement elementName: String, type: String?, defaultValue: String? ) "55-*45TRVBSFXJEUI$%"5"3&26*3&%
  54. ಺෦&/5*5: &/5*5:  YNMWFSTJPOFODPEJOH65'  %0$5:1&CPPLT< &/5*5:BVUIPSՆ໨ᕸੴ >  CPPLTOBNFॻ੶৘ใ

    CPPL UJUMFࡾ࢛࿠UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMFͦΕ͔ΒUJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMF໳UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPLT ಺෦&/5*5:Ͱஔ͖׵͑
  55. optional func parser( _ parser: XMLParser, foundInternalEntityDeclarationWithName name: String, value:

    String? ) ಺෦&/5*5:ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE*OUFSOBM&OUJUZ%FDMBSBUJPO8JUI/BNFWBMVF parser An NSXMLParser object parsing XML. name A string that is the declared name of an internal entity. value A string that is the value of entity name.
  56. ಺෦&/5*5:ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE*OUFSOBM&OUJUZ%FDMBSBUJPO8JUI/BNFWBMVF ༧૝ ࣮ࡍ OBNF BVUIPS BVUIPS WBMVF Ն໨ᕸੴ

    Ն໨ᕸੴ &/5*5:BVUIPSՆ໨ᕸੴ optional func parser( _ parser: XMLParser, foundInternalEntityDeclarationWithName name: String, value: String? )
  57. ಺෦&/5*5: &/5*5: func parser(_ parser: XMLParser, foundCharacters string: String) {

    print(string) } ಺༰͸Ͳ͏ग़ྗ͞ΕΔʁ CPPLTOBNFॻ੶৘ใ CPPL UJUMFࡾ࢛࿠UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMFͦΕ͔ΒUJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMF໳UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPLT
  58. ಺෦&/5*5: &/5*5: func parser(_ parser: XMLParser, foundCharacters string: String) {

    print(string) // Ն໨ᕸੴ } ಺༰͸Ͳ͏ग़ྗ͞ΕΔʁ CPPLTOBNFॻ੶৘ใ CPPL UJUMFࡾ࢛࿠UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMFͦΕ͔ΒUJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMF໳UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPLT
  59. ಺෦&/5*5: &/5*5: func parser(_ parser: XMLParser, foundCharacters string: String) {

    print(string) // &author; } ಺༰͸Ͳ͏ग़ྗ͞ΕΔʁ CPPLTOBNFॻ੶৘ใ CPPL UJUMFࡾ࢛࿠UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMFͦΕ͔ΒUJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMF໳UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPLT
  60. ಺෦&/5*5: &/5*5: func parser(_ parser: XMLParser, foundCharacters string: String) {

    print(string) // \n } վߦจࣈ͕͘Δˠม׵Ͱ͖ͳ͍ CPPLTOBNFॻ੶৘ใ CPPL UJUMFࡾ࢛࿠UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMFͦΕ͔ΒUJUMF BVUIPSBVUIPSBVUIPS CPPL CPPL UJUMF໳UJUMF BVUIPSBVUIPSBVUIPS CPPL CPPLT
  61. optional func parser( _ parser: XMLParser, foundExternalEntityDeclarationWithName name: String, publicID:

    String?, systemID: String? ) ֎෦&/5*5:ղੳ༻9.-1BSTFS%FMFHBUF QBSTFS @GPVOE&YUFSOBM&OUJUZ%FDMBSBUJPO8JUI/BNFQVCMJD*%TZTUFN*% 
  62. 9.-1BSTFSͰͷ֎෦&/5*5: &/5*5:  YNMWFSTJPOFODPEJOHVUG  %0$5:1&UFTU< &/5*5:FYUFSOBM4:45&.VTFS fi MFYNM >

    UFTUFYUFSOBMUFTU func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) { print(#function, #line, "parseError", parseError) } parser(_:parseErrorOccurred:) 45 parseError Error Domain=NSXMLParserErrorDomain Code=104 "(null)" UserInfo={NSXMLParserErrorColumn=17, NSXMLParserErrorLineNumber=5, NSXMLParserErrorMessage=Failure to process entity external }
  63. switch xmlParser.externalEntityResolvingPolicy { case .never: print("never") // ← Default case

    .noNetwork: print("noNetwork") case .sameOriginOnly: print("sameOriginOnly") case .always: print("always") @unknown default: print("default") } 9.-1BSTFSͰ%0. 6TJOH.VMUJQMF%FMFHBUFT σϑΥϧτͰ͸OFWFS͕ઃఆ͞Ε͍ͯΔ
  64. switch xmlParser.externalEntityResolvingPolicy { case .never: print("never") // ← Default case

    .noNetwork: print("noNetwork") case .sameOriginOnly: print("sameOriginOnly") case .always: print("always") @unknown default: print("default") } xmlParser.externalEntityResolvingPolicy = .noNetwork // or .always 9.-1BSTFSͰ%0. 6TJOH.VMUJQMF%FMFHBUFT ֎෦&OUJUZ͕ fi MFͷ৔߹ɺOP/FUXPSL΍BMXBZTʹઃఆ͢Δ
  65. 9.-1BSTFSͰͷ֎෦&/5*5: &/5*5:  YNMWFSTJPOFODPEJOHVUG  %0$5:1&UFTU< &/5*5:FYUFSOBM4:45&.VTFS fi MFYNM >

    UFTUFYUFSOBMUFTU JUFN UJUMFχϡʔελΠτϧUJUMF MJOLIUUQTFYBNQMFDPN MJOL QVC%BUF'SJ .BZ (.5QVC%BUF EFTDSJQUJPOχϡʔεهࣄ EFTDSJQUJPO DPNNFOUTIUUQT FYBNQMFDPNDPNNFOUT DPNNFOUT JUFN VTFS fi MFYNM
  66. 9.-1BSTFSͰͷ֎෦&/5*5: &/5*5:  YNMWFSTJPOFODPEJOHVUG  UFTU JUFN UJUMFχϡʔελΠτϧUJUMF MJOLIUUQTFYBNQMFDPNMJOL QVC%BUF'SJ

    .BZ (.5QVC%BUF EFTDSJQUJPOχϡʔεهࣄ EFTDSJQUJPO DPNNFOUTIUUQT FYBNQMFDPNDPNNFOUTDPNNFOUT JUFN UFTU JUFN UJUMFχϡʔελΠτϧUJUMF MJOLIUUQTFYBNQMFDPN MJOL QVC%BUF'SJ .BZ (.5QVC%BUF EFTDSJQUJPOχϡʔεهࣄ EFTDSJQUJPO DPNNFOUTIUUQT FYBNQMFDPNDPNNFOUT DPNNFOUT JUFN ֎෦ϑΝΠϧͷ಺༰ʹஔ͖׵ΘΔ VTFS fi MFYNM