Ant xmlproperty task fails due to validation error - ant

I want to extract an application version from a DITA map file. The ditamap file is valid and looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
<map id="user-manual">
<title><ph keyref="product"/> User Manual</title>
<topicmeta>
<prodinfo>
<prodname><keyword keyref="product"/></prodname>
<vrmlist>
<vrm version="4" release="3" modification="0"/>
</vrmlist>
</prodinfo>
</topicmeta>
<!--
[...]
-->
</map>
The information I want to get is in the <vrm> element.
"Easy peasy," I think to myself. So I use Ant's <xmlproperty> task to just load this XML file.
<project default="test">
<!-- notice #validate -->
<xmlproperty file="path/to/user-manual.ditamap" validate="false"/>
<target name="test">
<echo>${map.topicmeta.prodinfo.vrmlist.vrm(version)}</echo>
</target>
</project>
I don't want it to validate because Ant isn't going to find map.dtd.
Loading the file returns an error:
java.io.FileNotFoundException: /home/user/user-manual/map.dtd (No such file or directory)
If I remove the <!DOCTYPE> declaration or add a nested <xmlcatalog> with the path to the DTD, the file loads and I can use the properties from it.
I tested this with Ant 1.7.1 and 1.9.4. Is this a bug with Ant, or am I misunderstanding how Ant loads XML properties and the purpose of the validate attribute?
How can I make Ant obey my will?

I recommend to not use the <xmlproperty> for this. Please have a look at the docs:
For example, with semantic attribute processing enabled, this XML
property file:
<root>
<properties>
<foo location="bar"/>
<quux>${root.properties.foo}</quux>
</properties>
</root>
is roughly equivalent to the following fragments in a build.xml file:
<property name="root.properties.foo" location="bar"/>
<property name="root.properties.quux" value="${root.properties.foo}"/>
So the name of the properties you set is generated using their paths to the root element, so they rely on the structure of your DITA Map. But many elements in DITA may be set at different positions on your DITA Map. That means, if you move your metadata to another parent element, the property name changes and your build fails. This is probably not, what you want.
I'd recommend to grab those values via XSLT and than set the properties. That way, you could, for example, say, "give me the first occurance of that element with a simple //foo[1] XPath selector. Further on, you have the power of XSLT and XPath to slice values, format dates and so on before setting a property.
Update
You can use the oops consultancy Ant xmltask for that. It is very easy to set a property using <copy>:
<copy path="//critdates/created/#date"
property="document.date"
append="false"/>

Related

ANT script : xmlcatalog not reading local dtd

I have XML file named TIBCOUniversalInstaller_TRA_5.10.0.silent as below.I want to replace values in XML file using "replace" target in ant script using xmltask task.
XML File is below:
<?xml version="1.0"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>---Universal Installer Silent Installation Properties---</comment>
<!--accept the license agreement-->
<entry key="acceptLicense">true</entry>
<entry key="installationRoot">/opt/tibco</entry>
<entry key="environmentName">TRA</entry>
</properties>
At time of parsing XML file ,since my server can not reach java.sun.com , so i had downloaded properties.dtd on my local machine and using xmlcatalog task i am forcing ant script to read local copy of properties.dtd.Below is my ant script
<xmlcatalog id="dtd">
<dtd publicId="SYSTEM" location="/home/tibco/BW-AUTOMATION-
PROJECT/Environments/properties.dtd"/>
</xmlcatalog>
<xmltask source="${TRASoftwareFolder}/TIBCOUniversalInstaller_TRA_5.10.0.silent" dest="${TRASoftwareFolder}/TIBCOUniversalInstaller_TRA_5.10.0.silent">
<xmlcatalog refid="dtd">
</xmlcatalog>
<replace path="/:properties/:entry/:[#key='installationRoot']/text()"
withText="/home/tibco"/>
</xmltask>
But still at time of parsing XML contents , everytime it is going to http://java.sun.com/dtd/properties.dtd and i get "Connection Refused Error".
When i did debug i see below which i believe can be issue and it is always going to website instead of local dtd file.
DEBUG LOGS:
"No matching catalog entry found, parser will use: 'http://java.sun.com/dtd/properties.dtd'"
I believe it is because i gave "SYSTEM" as value in "publicId" attribute inside dtd element.
Can you please advise what should be correct value for "publicID" attribute for this given dtd so that it matches catalog at the time of parsing.
If there is another way of reading/replacing this XML file please advise.
Thanks

How use property expansion in a Launch4j config file

I use Launch4j and will use a property ${dist} in its configuration.
It works when the task and it argument directly are in the build.xml file:
<project ...>
<property name="dist" location="/temp/dist" />
<launch4j>
<config headerType="gui" outfile="${dist}/myprogram.exe"
dontWrapJar="false" jarPath="${dist}/myprogram.jar">
...
</config>
</launch4j>
</project>
Launch4j can however use its own xml-configuration file, with <launch4jConfig> as root element:
in ant.xml:
<launch4j configFile="my_launch4j_config.xml" />
in my_launch4j_config.xml:
<launch4jConfig>
<headerType>gui</headerType>
<outfile>${dist}/myprogram.exe</outfile>
<dontWrapJar>false</dontWrapJar>
<jar>${dist}/myprogram.jar</jar>
...
</launch4jConfig>
In this case, ${dist} is not expanded, nor %dist% or everything I tried... Does a solution exist to use properties in an launch4j config file?
The code of launch4j did not accept such replacements of parameters, but I could change this behaviour (modifications to net.sf.launch4j.config.ConfigPersister). I check it in the Sourceforge project when I have enough time for it.

The prefix "sonar" for element "sonar:sonar" is not bound

I have a build.xml-file that looks something like this:
<taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml" classpath="/path/sonar-ant-task.jar"/>
<target name="sonar">
<sonar:sonar/>
</target>
And when I run the file I get:
The prefix "sonar" for element "sonar:sonar" is not bound.
Any obvious things I'm missing?
You're missing the namespace declaration in the top project element of your Ant script.
xmlns:sonar="antlib:org.sonar.ant" ought to do it.
In ant you can not use .
try below and if you are setting any properties use key value pare in xml tag.
To allocate value use attributes of xml tags.
<sonar:sonar xmlns:sonar="antlib:org.sonar.ant">
</sonar:sonar>

How to validate an xml file in ant?

this is my xml file
<contacts>
<contact>
<firstname>Edwin</firstname>
<lastname>Dankert</lastname>
</contact>
</contacts>
i want to validate it in ant,my target is
<target name="WellFormed">
<xmlvalidate file="contacts.xml"/>
<echo>WELL FORMED</echo>
</target>
C:\work\build\XML_VALIDATION>ant
Buildfile: C:\work\build\XML_VALIDATION\build.xml
<==========================ANT OUTPUT=============================>
WellFormed:
[xmlvalidate] contacts.xml:1:11: Document root element "contacts", must match DOCTYPE root "null".
[xmlvalidate] contacts.xml:1:11: Document is invalid: no grammar found.
BUILD FAILED
C:\work\build\XML_VALIDATION\build.xml:4: C:\work\build\XML_VALIDATION\contacts.xml is not a valid XML document.
i am not checking it against any xsd,can anyone help me in finding what changes i need to insert into the xml.
If you just want to make sure your XML is well-formed, then add the lenient attribute to your xmlvalidate task as follows.
<xmlvalidate file="contacts.xml" lenient="yes"/>
Your build file is not valid, you need to start with
<?xml version="1.0"?>
<project name="name">
<target name="target-name">
...
</target>
</project>
A google search for sample Ant build file will provide all you need to understand build files. This link will help too.

Is it possible to pass a string containing xml as input to the ant xslt task?

Trying to find out if it's possible to pass a string containing xml as input to the ant xslt task. Thanks!
The short answer is 'no'. But the slightly longer answer is: you can achieve the same by other means.
In one mode, the Ant xslt task will style the file specified by the in attribute, storing the result in the file specified by the out attribute.
<xslt in="src.xml" out="dest.xml" ...>
...
</xslt>
So, if you have the XML you want to process stored in an Ant property, you can write that out to 'src.xml' and have it processed by xslt. You can write the property ${xml}(the string) out to a file using something like:
<property name="xml"><![CDATA[
<myxml>
...
</myxml>]]>
</property>
<echo file="src.xml" message="${xml}" />
Alternatively you might use the echoxml task:
<echoxml file="src.xml">
<myxml>
...
</myxml>
</echoxml>
Which method you use will depend on the origin of the 'string'; whether it is raw text, or well-formed XML.
<xslt ...>
<style>
<string>
<![CDATA[
<xsl:stylesheet ...>
... rest of xslt ...
</xsl:stylesheet>
]]>
</string>
</style></xslt>

Resources