【问题标题】:Replacing an entire XML tag using ANT使用 ANT 替换整个 XML 标记
【发布时间】:2012-04-10 20:55:58
【问题描述】:

PhoneGap Build 提供了一项服务(目前在测试期间免费),他们获取您的 HTML+JS+CSS 源代码,以及用于配置构建选项 (config.xml) 的 XML 文件,并为所有受支持的服务器进行构建平台(iOS、Android、Blackberry、Symbian、WebOS),这可以节省大量时间,并为我节省大量用于头痛药物的费用。

很遗憾,there is inconsistent behavior with the way links to external websites work

目前为了在外部浏览器中打开链接,需要将不同的代码上传到 PhoneGap Build。对于 iOS,必须将域列入白名单,而对于 Android,必须将域排除在外。

您可以通过向访问标签添加一个属性来使其保持一致,例如 includeForAndroid="false",它不会在 Android 上包含访问标签内容,这样链接就会在外部浏览器中打开,就像在 iOS 上一样。

Config.xml docs;这是a relevant blog post

虽然员工提出了修复建议,但尚未在产品中制作和发布:

我们希望在 Cordova 开源项目中解决这个问题:与此同时,对于 PhoneGap Build,我正在考虑这样的事情:

<access origin="*" onlyInBrowser="true" />

在 Android 上不包括标签,但在 iOS 上会。

在进行此更改并在产品中可用之前,解决方法是制作两个我将上传的 zip 文件:一个用于 Android(不带访问标签),另一个用于 iOS(带访问标签)。不理想,但必须这样做才能获得一致的应用行为。

我已经在使用 ANT 来自动化这个项目中的许多任务,所以如果 ANT 也可以为我完成 config.xml 更新,那将是理想的选择。

作为参考,这是我构建两个 zip 的 ANT 代码:

<target name="BUILD-ZIP" depends="verify-using-minified-js,prepare-for-build">

    <tstamp>
        <format property="build.tstamp" pattern="yyyy-MM-dd__HH-mm-ss" />
    </tstamp>
    
    <antcall target="zip-ios">
        <param name="tstamp" value="${build.tstamp}" />
    </antcall>
    
    <!-- build android second so that we can just remove the access tags -->
    <antcall target="zip-android">
        <param name="tstamp" value="${build.tstamp}" />
    </antcall>
        
</target>

<target name="zip-ios">
    <zip destfile="${dir.pkg.phonegap}${tstamp}-apple.zip">
        <zipfileset dir="${dir.pkg.tmp}">
            <exclude name="build.xml" />
            <exclude name="build.properties" />
            <exclude name="settings.xml" />
            <exclude name=".project" />
            <exclude name="**/*.psd" />
            <exclude name="assets/js/app.js" />
            <exclude name="assets/js/cordova-1.5.0.js" />
        </zipfileset>
    </zip>
</target>

<target name="zip-android">
    
    <!-- before building android zip, get rid of the <access> tags -->
    
    <zip destfile="${dir.pkg.phonegap}${tstamp}-android.zip">
        <zipfileset dir="${dir.pkg.tmp}">
            <exclude name="build.xml" />
            <exclude name="build.properties" />
            <exclude name="settings.xml" />
            <exclude name=".project" />
            <exclude name="**/*.psd" />
            <exclude name="assets/js/app.js" />
            <exclude name="assets/js/cordova-1.5.0.js" />
        </zipfileset>
    </zip>
</target>
    
<target name="prepare-for-build">
    
    <!-- increment build number -->
    <propertyfile file="build.properties">
        <entry key="version.build.number" type="int" operation="+" default="1"/>
    </propertyfile>
    <property file="build.properties"/>
    <echo message="BUILD NUMBER: ${version.build.number}"/>
    
    <delete includeemptydirs="true" verbose="false">
        <fileset dir="${dir.pkg.tmp}" includes="**/*"/>
    </delete>
    <filter token="BUILD_NUMBER" value="${version.build.number}" />
    <filter token="VERSION_MAJOR" value="${version.major}" />
    <filter token="VERSION_MINOR" value="${version.minor}" />
    <copy todir="${dir.pkg.tmp}" verbose="true" overwrite="true" filtering="true">
        <fileset dir="${dir.dev}" includes="**/*" />
    </copy>
    
</target>

zip-android 目标中有一条评论:

<!-- before building android zip, get rid of the <access> tags -->

这是我要进行替换的地方。我尝试过使用&lt;filter&gt; 任务以及&lt;replace&gt;&lt;replaceRegExp&gt;,但我似乎找不到方法,这一切都归结为我需要替换字符串:&lt;access ... /&gt; 并且这些替换方法似乎都不允许在 token/match/etc 属性中使用&lt;&gt;。我尝试过使用 CDATA,但也无法正常工作。

我最接近的,因为 ANT 不会抛出任何错误,是这样的:

<replace file="${dir.pkg.tmp}config.xml" failOnNoReplacements="true">
    <replacetoken>
        <![CDATA[<access origin="http://example.com" subdomains="true" />]]>
    </replacetoken>
</replace>

理论上,这会将指定的&lt;access ... /&gt; 标记替换为空字符串because I've omitted the value attribute

不幸的是,由于failOnNoReplacements 属性以及无论出于何种原因,它没有进行任何替换这一事实,它都失败了。

这可能吗?如果是这样,我做错了什么?!

【问题讨论】:

    标签: xml ant


    【解决方案1】:

    如果您在令牌和值中都对 XML 字符串的元素进行编码,则 Ant 替换任务将起作用...例如:

    在 config.xml 中

        <option name="some.unwanted.configuration" />
    

    在 build.xml 中

        <replace file="${build.dir}/config.xml"
            token="&lt;option name=&quot;some.unwanted.configuration&quot; /&gt;" 
            value="&lt;!-- unwanted configuration removed --&gt;"
        />
    

    结果

        <!-- unwanted configuration removed -->
    

    【讨论】:

      【解决方案2】:

      哈,我设法提出了一个解决尖括号阻塞的解决方案。

      在 config.xml 中:

      <!--access_tag1_here-->
      

      在 build.xml 中:

      <replace 
          file="${dir.pkg.tmp}config.xml" 
          failOnNoReplacements="true"
          token="!--access_tag1_here--" 
          value="access origin='http://example.com' subdomains='true' /"
          />
      

      这会将注释转换为必要的访问标记。

      我切换了我的 zip 顺序,现在 Android 先行,而 cmets 仍然是 cmets,然后 iOS zip 进程插入访问标签。

      【讨论】:

        【解决方案3】:

        在处理 xml 时,我推荐 xmltask
        对于您的需求,请参阅:xml task manual replace
        一点 Xpath 知识会派上用场,请参阅:
        http://zvon.org/xxl/XPathTutorial/
        http://www.w3schools.com/xpath/

        【讨论】:

          猜你喜欢
          • 2011-01-07
          • 2012-06-20
          • 2019-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-10
          • 2013-05-04
          相关资源
          最近更新 更多