Reputation: 1960
I'm using libxml2 to parse xml documents for my application. I want the ability to use variables and even function calls in the XML. For example, something like:
< Element attr1="$variable1" attr2="=rand(1, 2, 3, 4)" />
The variables may be defined in the XML and reused, or defined/hardcoded somewhere in the code loading the XML. The functions may be defined in the code (i.e. calling C functions from the XML).
My application already loads XML documents and I can load and modify the XML in memory, but I would like to know: what is the best way to evaluate the variables and function calls?
Are there any XML libraries or interpreter libraries that I can use?
Upvotes: 0
Views: 973
Reputation: 129454
You will have to implement a simple parser (or complex, depending on what you need), which can understand variables and functions.
First step is to extract the expressions from attr1="$variable1"
- in the simple case, that's just a matter of looking at the first character inside the string to see if it's a '$'
or '='
.
If all variables are integers, you can easily store variables in a std::map<std::string, int>
. If the value is allowed to be multiple types, then you can either store the value as a string (and convert as needed), or have a struct/class that includes information about what the actual content type is.
Evaluating expressions like =rand(1,2,3,4)
would involve some sort of "string to function" construct. A very simple way is an if/else chain. Here we assume that you have extracted the function name as a standalone string called funcname
if (funcname == "rand")
{
... do stuff here...
}
else if (funcname == "sin")
{
....
}
A more complex, but often more effective solution is to have a structure that contains a string and a function pointer. Search for the string, and call the function.
Another alternative is to use std::map<std::string, functionType>
where functionType
is a typedef of a standardized function.
Bot of the latter two solutions pretty much relies on having a standard function type. You can standardise the function by for example having a std::vector<Arg> args
as the arguments - the functions can check the number of arguments with if (args.size() != 4) print_error("wrong number of arguments");
.
I hope this helps you along the way...
Upvotes: 1