2

My Xml looks like:

<root>
        <foo location="bar"/>
        <foo location="in" flag="123"/>
        <foo location="pak"/>
        <foo location="us" flag="256"/>
        <foo location="blah"/>
</root>

For foo xml element flag is optional attribute.

And when I say:

<xmlproperty file="${base.dir}/build/my.xml" keeproot="false"/>

 <echo message="foo(location) : ${foo(location)}"/>

prints all locations :

foo(location) : bar,in,pak,us,blah

Is there a way to get locations only if flag is set to some value?

user1587504
  • 764
  • 1
  • 10
  • 25

1 Answers1

6

Is there a way to get locations only if flag is set to some value?

Not with xmlproperty, no, as that will always conflate values that have the same tag name. But xmltask can do what you need as it supports the full power of XPath:

<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask">
  <classpath path="xmltask.jar" />
</taskdef>

<xmltask source="${base.dir}/build/my.xml">
  <copy path="/root/foo[@flag='123' or @flag='256']/@location"
        property="foo.location"
        append="true" propertySeparator="," />
</xmltask>
<echo>${foo.location}</echo><!-- prints in,us -->

If you absolutely cannot use third-party tasks then I'd probably approach the problem by using a simple XSLT to extract just the bits of the XML that you do want into another file:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:param name="targetFlag" />

  <xsl:template name="ident" match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
  </xsl:template>

  <xsl:template match="foo">
    <xsl:if test="@flag = $targetFlag">
      <xsl:call-template name="ident" />
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Call this with the xslt task

<xslt in="${base.dir}/build/my.xml" out="filtered.xml" style="extract.xsl">
  <param name="targetFlag" expression="123" />
</xslt>

This will create filtered.xml containing just

<root>
        <foo location="in" flag="123"/>
</root>

(modulo changes in whitespace) and you can load this using xmlproperty in the normal way.

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • Thanks for sharing this. But I am looking more form apache's built in ant-tasks. seems like I need to build some with propertyregex or related ones – user1587504 Oct 23 '13 at 15:33
  • @user1587504 It seems unduly harsh to restrict yourself like that when there are third-party tasks out there that will make your life much easier, but I've added a possible alternative approach using XSLT. Note that while it's not made clear in the xmltask docs, you don't actually need to "install" anything or modify your global classpath to use the task, just drop the jar in your project directory and give a `` to the taskdef. – Ian Roberts Oct 23 '13 at 15:46
  • I agree that there is a cost when venturing outside the built-in tasks... however regex on xml is not the path. excellent reading: http://stackoverflow.com/a/1732454/505191 – thekbb Oct 23 '13 at 15:48
  • +1 for the use of xmltask. Essential task for any xml driven ant build, means a build based on a xmlproperty file. The quote : "...too essential to be left out of the Ant distribution..." from http://www.oopsconsultancy.com/software/xmltask/ is definitely right. – Rebse Oct 23 '13 at 20:35
  • Great but not available on Maven Central. – Michael-O Mar 21 '14 at 11:24