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

发布于 2024-12-02 12:04:26 字数 186 浏览 1 评论 0原文

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

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

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

There's an XML file on some remote server (http://foo/bar.xml):

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

How can I get the value "bar" using AppleScript?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

三生池水覆流年 2024-12-09 12:04:26

这是我所做的:

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 下都可以工作。

Here's what I've done:

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

Originally I was using the "URL Access Scripting" app to fetch the file, but since it has been removed in Lion, I switched to pure curl, which works under both Snow Leopard and Lion.

已下线请稍等 2024-12-09 12:04:26

我发现 此线程 其中有一个解析 XML 文件的示例使用通过系统事件提供的 XML 工具。但对我来说似乎很复杂。

还有这个(免费软件)脚本附加包用于解析/写入 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 解析,但这当然有点脆弱),但我就到此为止:)

I found this thread which has an example of parsing an XML file with the XML tools available via System Events. Seems pretty convoluted to me though.

There's also this (freeware) scripting addition package for parsing/writing XML. Haven't looked at it, but it might be neat.

Personally, I would save my script as a script bundle, and then I'd make a little php/Ruby/perl/python/whatever script to parse the XML (since I'm just more comfortable with that) in the bundle. Then I'd use AppleScript then pass the XML to the parser script from 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 could be somthing like this (using Ruby as an example):

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 and the REXML package should be readily available on any Mac, so it should work anywhere… I believe)

Point is, when the script runs it'll download the XML file with cURL, pass it to the Ruby script, and in the end, fooValue in the AppleScript will be set to "bar".

Of course, if the XML is more complex, you'll need more scripting, or take another look at the other options.

There are probably even more ways of doing it (for instance, you could just do some string manipulation instead of full-on XML parsing, but that's a little brittle of course), but I'll stop here :)

°如果伤别离去 2024-12-09 12:04:26

意识到这是一个老问题,但这是使用 Bing Maps API 的一种方法(请注意,我将 API 密钥替换为 XXXXXXXXXX)。使用 do shell scriptcurl 来检索 XML,然后沿着元素向下查找,直到找到所需的元素(您可以合并所有 tell< /code>s 到 告诉 xml 元素“X”的 xml 元素“y”的 xml 元素...,但这更容易理解)。

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>

Realizing this is an old question, but here’s one way using the Bing Maps API (note I replaced my API key with XXXXXXXXXX). use do shell script with curl to retrieve the XML, then just walk down the elements until you get to the one you need (you can consolidate all the tells into tell xml element “X” of xml element “y” of xml element…, but this is just easier to follow).

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

EDIT: I suppose I should include the XML I was using for the above:

<?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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文