xmacro
is a simple tool to define and parse XML macro. it's inspired by ros/xacro which is an XML macro language desiged for urdf
. xmacro
looks like a simplified version of ros/xacro
, it's simpler, but it works well for xml files like urdf
and sdf
). in addition it's flexible, and also easy to use.
xmacro
is independent of ROS, you could install it bypip
.- XML namespace isn't used in
xmacro
, there are some reserved tags:xmacro_include
,xmacro_define_value
,xmacro_define_block
,xmacro_block
. - it provides python api so that we could parse xml file in ROS2 launch file.
Installation
# install by pip
pip install xmacro
# install from source code
git clone https://github.com/gezp/xmacro.git
cd xmacro && sudo python3 setup.py install
examples
# some examples in folder test/xmacro
xmacro test_xmacro_block.xml.xmacro > test_xmacro_block.xml
- Value macro
- Block macro
- Math expressions
- Include
- Python API
Value macro are named values that can be inserted anywhere into the XML document except <xmacro_define_block>
block.
xmacro definition
<!--definition of properties -->
<xmacro_define_value name="radius" value="4.3" />
<!--use of properties-->
<circle diameter="${2 * radius}" />
generated xml
<circle diameter="8.6" />
Define block macros with the macro tag <xmacro_define_block>
, then specify the macro name and a list of parameters. The list of parameters should be whitespace separated.
The usage of block macros is to define <xmacro_block>
which will be replaced with corresponding <xmacro_define_block>
block.
xmacro definition
<!--definition of macro-->
<xmacro_define_value name="mass" value="0.2" />
<xmacro_define_block name="box_inertia" params="m x y z">
<mass>${m}</mass>
<inertia>
<ixx>${m*(y*y+z*z)/12}</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>${m*(x*x+z*z)/12}</iyy>
<iyz>0</iyz>
<izz>${m*(x*x+z*z)/12}</izz>
</inertia>
</xmacro_define_block>
<!--use of macro-->
<inertial>
<pose>0 0 0.02 0 0 0</pose>
<xmacro_block name="box_inertia" m="${mass}" x="0.3" y="0.1" z="0.2"/>
</inertial>
generated xml
<inertial>
<pose>0 0 0.02 0 0 0</pose>
<mass>0.2</mass>
<inertia>
<ixx>0.0008333333333333335</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.002166666666666667</iyy>
<iyz>0</iyz>
<izz>0.002166666666666667</izz>
</inertia>
</inertial>
- only support simple parameters (string and number), and block parameters isn't supported.
- it's supported to use other
xmacro_block
inxmacro_define_block
which is recursive definition (the max nesting level is 5).
condition block
a example here (you could find more examples in test/xmacro/test_xmacro_condition.xml.xmacro
)
<!--use of macro-->
<inertial>
<pose>0 0 0.02 0 0 0</pose>
<xmacro_block name="box_inertia" m="${mass}" x="0.3" y="0.1" z="0.2" condition="${mass==0.2}"/>
</inertial>
- the
condition
can beTrue
,False
,1
,0
, we can also use math expression to define condition, but operator<
and>
isn't supported in math expression. - if
condition
isFalse
or0
, thexmacro_block
wou't be loaded. condition
is reserved attribute of<xmacro_block>
, socondition
can't be used asparams
of<xmacro_define_block>
.
- within dollared-braces
${xxxx}
, you can also write simple math expressions. - refer to examples of Value macro and Block macro
- it's implemented by calling
eval()
in python, so it's unsafe for some cases.
You can include other xmacro files by using the <xmacro_include>
tag.
- it will include the xmcaro definition with tag
<xmacro_define_value>
and macros with tag<xmacro_define_block>
.
<xmacro_include uri="file://simple_car/model.sdf.xmacro"/>
- The uri for
file
means to open the file directly.- it try to open the file with relative path
simple_car/model.sdf.xmacro
. - you can also try to open file with absolute path
/simple_car/model.sdf.xmacro
with urifile:///simple_car/model.sdf.xmacro
.
- it try to open the file with relative path
<xmacro_include>
supports to include recursively.
you can use xmacro
in python easily
from xmacro.xmacro import XMLMacro
xmacro=XMLMacro()
#case1 parse from file
xmacro.set_xml_file(inputfile)
xmacro.generate()
xmacro.to_file(outputfile)
#case2 parse from xml string
xmacro.set_xml_string(xml_str)
xmacro.generate()
xmacro.to_file(outputfile)
#case3 generate to string
xmacro.set_xml_file(inputfile)
xmacro.generate()
xmacro.to_string()
#case4 custom macro value
xmacro.set_xml_file(inputfile)
# use custom dictionary to overwrite global macro value defined by <xmacro_define_value>
kv={"rplidar_a2_h":0.8}
xmacro.generate(kv)
xmacro.to_file(outputfile)
maintainer : Zhenpeng Ge, [email protected]
xmacro
is provided under MIT License.