如何使用AppleScript获取和解析XML文件?

时间:2011-09-02 07:27:47

标签: applescript

某个远程服务器上有一个XML文件(http://foo/bar.xml):

<?xml version="1.0" encoding="UTF-8"?> 
<foo> 
  bar
</foo>

如何使用AppleScript获取值“bar”?

3 个答案:

答案 0 :(得分:4)

这就是我所做的:

set file_tgt to (POSIX path of (path to temporary items)) & "file.xml"
    do shell script "curl -L " & "http://url.com/file.xml" & " -o " & file_tgt
tell application "System Events"
    set file_content to contents of XML file file_tgt
    tell file_content
        set my_value to value of XML element 1
    end tell
end tell

最初我使用的是“URL Access Scripting”应用程序来获取文件,但由于它已经在Lion中删除,我转而使用纯卷曲,它可以在Snow Leopard和Lion下运行。

答案 1 :(得分:2)

我发现this thread有一个使用系统事件提供的XML工具解析XML文件的示例。看起来对我来说很复杂。

还有这个(免费软件)scripting addition package用于解析/编写XML。没看过,但它可能很整洁。

就个人而言,我会将我的脚本保存为脚本包,然后我会制作一些php / Ruby / perl / python /无论什么脚本来解析XML(因为我对此更加熟悉)束。然后我使用AppleScript然后将XML传递给cURL的解析器脚本。

的AppleScript:

set scriptPath to POSIX path of (path to me as alias) & "Contents/Resources/parse_xml.rb"
set fooValue to do shell script "curl http://foo/test.xml 2> /dev/null | ruby " & quoted form of scriptPath

parse_xml.rb可能是这样的(以Ruby为例):

require "rexml/document"

# load and parse the xml from stdin
xml = STDIN.read
doc = REXML::Document.new(xml)

# output the text of the root element (<foo>) stripped of leading/trailing whitespace
puts doc.root.text.strip

(Ruby和REXML软件包应该可以在任何Mac上随时使用,因此它可以在任何地方使用......我相信)

重点是,当脚本运行时,它将使用cURL下载XML文件,将其传递给Ruby脚本,最后,AppleScript中的fooValue将设置为“bar”。

当然,如果XML更复杂,您需要更多脚本,或者再看看其他选项。

可能有更多的方法(例如,你可以只做一些字符串操作而不是全面的XML解析,但当然有点脆弱),但我会停在这里:)

答案 2 :(得分:0)

实现这是一个老问题,但这是使用Bing Maps API的一种方式(注意我用XXXXXXXXXX替换了我的API密钥)。使用do shell scriptcurl来检索XML,然后向下走元素,直到找到所需的元素(您可以将所有tell合并到tell xml element “X” of xml element “y” of xml element…,但这更容易理解。

set theXML to make new XML data with properties {name:"Geolocation", text:(do shell script "curl 'http://dev.virtualearth.net/REST/v1/Locations?&q=638%20Brandon%20Town%20Center%20Brandon%20FL%2033511&o=xml&key=XXXXXXXXXX'")}
tell theXML
    tell XML element "Response"
        tell XML element "ResourceSets"
            tell XML element "ResourceSet"
                tell XML element "Resources"
                    tell XML element "Location"
                        tell XML element "Point"
                            set theLatitude to the value of XML element "Latitude"
                            set theLongitude to the value of XML element "Longitude"
                        end tell
                    end tell
                end tell
            end tell
        end tell
    end tell
end tell

编辑:我想我应该包含我上面使用的XML:

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<Response xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.microsoft.com/search/local/ws/rest/v1\">
  <Copyright>Copyright © 2014 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
  <BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
  <StatusCode>200</StatusCode>
  <StatusDescription>OK</StatusDescription>
  <AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
  <TraceId>06bb657f1ac9466ba00ef45aa55aef3b|BN20130631|02.00.108.1000|BN2SCH020180822, BN2SCH020181444, BN2SCH020181020, BN2SCH030291220, BN2SCH030261523</TraceId>
  <ResourceSets>
    <ResourceSet>
      <EstimatedTotal>1</EstimatedTotal>
      <Resources>
        <Location>
          <Name>638 Brandon Town Center Dr, Brandon, FL 33511</Name>
          <Point>
            <Latitude>27.929752349853516</Latitude>
            <Longitude>-82.326362609863281</Longitude>
          </Point>
          <BoundingBox>
            <SouthLatitude>27.925889632282839</SouthLatitude>
            <WestLongitude>-82.332191670122214</WestLongitude>
            <NorthLatitude>27.933615067424192</NorthLatitude>
            <EastLongitude>-82.320533549604349</EastLongitude>
          </BoundingBox>
          <EntityType>Address</EntityType>
          <Address>
          <AddressLine>638 Brandon Town Center Dr</AddressLine>
          <AdminDistrict>FL</AdminDistrict>
          <AdminDistrict2>Hillsborough Co.</AdminDistrict2>
          <CountryRegion>United States</CountryRegion>
          <FormattedAddress>638 Brandon Town Center Dr, Brandon, FL 33511</FormattedAddress>
          <Locality>Brandon</Locality>
          <PostalCode>33511</PostalCode>
          </Address>
          <Confidence>High</Confidence>
          <MatchCode>Good</MatchCode>
          <GeocodePoint>
            <Latitude>27.929752349853516</Latitude>
            <Longitude>-82.326362609863281</Longitude>
            <CalculationMethod>Parcel</CalculationMethod>
            <UsageType>Display</UsageType>
          </GeocodePoint>
          <GeocodePoint>
            <Latitude>27.929159164428711</Latitude>
            <Longitude>-82.32720947265625</Longitude>
            <CalculationMethod>Interpolation</CalculationMethod>
            <UsageType>Route</UsageType>
          </GeocodePoint>
        </Location>
      </Resources>
    </ResourceSet>
  </ResourceSets>
</Response>