如何使用Ant更新XML文档

时间:2011-04-21 03:34:21

标签: xml ant xpath xml-namespaces

我的目标是简单地更新简单的站点地图xml文档中的“lastmod”节点:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>http://www.example.com/</loc>
        <lastmod>2005-01-01</lastmod>
    </url>
</urlset> 

我想在部署ant脚本中执行此操作,因此我使用Ant任务XMLTask。这是我的蚂蚁目标:

<target name="update-sitemap" description="update the update date">
    <xmltask source="war/sitemap.xml" dest="war/newsitemap.xml" report="true">
        <replace path="/urlset/url/lastmod/text()" withText="new text"/>
    </xmltask>
</target>

不幸的是,我的xpath无法匹配任何内容:

[xmltask] TextAction(new text) (/urlset/url/lastmod/text()) failed to match

我也尝试过以下xpath查询而没有运气:

//lastmod/text()
/urlset[@*]/url/lastmod/text()
/urlset[@xmlns]/url/lastmod/text()

但我发现如果我从源文件中的urlset节点手动删除namespace属性,一切正常。 这是XMLTask中的错误还是我做错了什么?

3 个答案:

答案 0 :(得分:4)

您需要告诉XPath所有节点都有一个命名空间,前缀是冒号。正确的表达方式是:

/:urlset/:url/:lastmod/text()

答案 1 :(得分:1)

我无法解决问题。我确定XMLTask在属性为“xmlns”时有一些问题,因为如果我将其重命名为其他东西(例如“xmln”),一切都按预期工作。

我只是简单地使用了一种稍微丑陋的正则表达式替换技术:

<replaceregexp byline="true">
    <regexp pattern="      &lt;lastmod&gt;(.*)&lt;/lastmod&gt;"/>
    <substitution expression="      &lt;lastmod&gt;new text&lt;/lastmod&gt;"/>
    <fileset file="war/sitemap.xml" />
</replaceregexp>

从好的方面来说,这不需要任何第三方库。

更新:现在解决了。看到我的其他答案。

答案 2 :(得分:0)

我需要在同一个ant文件中进行替换,因为正则表达式替换操作也会更新我的正则表达式模式本身。解决方案是不匹配正则表达式模式签名,例如,因此将起作用:

<replaceregexp file="${ant.file}"
    match='(name="staticresource.foldername_previous" value=")[^\[\]]*(")'  
    replace='\1${staticresource.foldername}\2'
    byline="true"
/>