I know that an immutable array on XSLT 3.0 can be created as follows:
<xsl:variable name="array" as="element()*">
<Item>a</Item>
<Item>b</Item>
<Item>c</Item>
</xsl:variable>
Also, that is it possible to create a mutable variable using Saxon's assign function:
<xsl:variable name="var" select="'val'" saxon:assignable="yes"/>
Is it possible to combine the two? i.e. creating a mutable array that allows editing individual items?
Note that due to some technical restrictions I am to use only XSLT/Saxon functions, so JavaScript is off the table, unfortunately.
Thanks!
Having a mutable variable is a quite different thing from having a variable that contains a mutable value. The only way you can create a mutable value in Saxon is to use an external Java object.
But why would you want to? Tell us what you want to achieve, and we can help you achieve it using XSLT the way it was designed to be used, working with the language rather than fighting against it.
Related
I have the following declarations:
<xsl:call-template name="ad_state800x100"><xsl:with-param name="state" select="/*/locations/#state" /></xsl:call-template>
And for the xpos
<xsl:variable name="xpos" select="substring-before(position(),'0')" />
What I want is the following:
<xsl:call-template name="ad$xpos_state800x100">
So if the position is 10, it will be:
<xsl:call-template name="ad1_state800x100">
How do I achieve this
If you want to make a dynamic decision which of several templates to invoke, the correct XSLT mechanism for doing that is xsl:apply-templates.
You haven't told us enough about your problem for me to know exactly how you would do this in your case, or indeed whether dynamic despatch needs to be part of the solution at all. In fact, you haven't told us anything about your problem - only an attempt at a solution that won't work.
I have good command over c++ language.I am interested in creating code which generates the object dynamically for which no schema has already been defined in code.First of all, is it possible to do so in c++? If yes, please anyone would guide me how to do it?
For example,
<name>android</name>
<count>5</count>
<version>4.4.4</version>
If this is given in file(.xml), the automatic object should be created and I should be able to access it.
TempObj.name, TempObj.count and TempObj.version etc..
No, you cannot do this at runtime in C++. Types have to be known at compile time in C++.
You can do code generation, i.e. read XML, generate C++, and compile. Or you can use a slightly different syntax (and much slower performance) to access the methods, basically:
typedef std::map<std::string, std::string> Object;
Object obj = load("whatever.xml");
assert(obj["name"] == "android");
But to do exactly what you've asked will require a different language. Tons of choices: Python and Lua are two that easily integrate with a C++ application directly, if you want that.
Using a hash table would solve your problem. in C++, the STL (standard template library) provides std::unordered_map<>
You should use that to solve your problem.
std::unordered_map<std::string, std::string> hm
The API is nice, where you can insert and change elements by using the [] operator.
hm["name"] = "android"
hm["count"] = "5";
hm["version"] = "4.4.4";
If you need dynamic types, you could probably use templates.
You may be wondering why you would use an ordered or an unordered map in C++. With an ordered map, all elements are able to iterated in the order they were inserted, whereas an unordered map the order in which you will access them is random based on the hashed value.
I'm looking for a simple-way to transform in C++ an object into XML string representation, so this way I could communicate with a server.
For instance, let us say I have an object:
class A{
string data1;
string data2;
string dataN;
list<B> bList;
}
class B{
string moreData;
}
I would like the following XML-representation:
(Assume that I have created one instance A and it has two instances of B)
<A>
<data1>content</data1>
<data2>content</data2>
<dataN>content</dataN>
<B>
<moreData>content</moreData>
</B>
<B>
<moreData>content</moreData>
</B>
</A>
What you describe is referred to as XML Data Binding.
There are a number of products that will generate the C++ code from and XSD or DTD, have a look at http://www.xmldatabinding.org/ for a list, and http://www.rpbourret.com/xml/XMLDataBinding.htm for more information.
Also have a look at this XML Data Binding example for C++, it shows the example source schema and generated code.
If your schemas are pretty basic and you have the ability to tune them to the generator then there are probably some open source projects that will do the job. If you are binding to an XML Standard then you quickly run up against the limitations of most generators. The Liquid XML generator copes with pretty much all XSD standards, but you have to pay for it.
There is no universal solution for this problem in C++, however many adhoc implementations exist.
This question has some remarkable links and how-tos: How to implement serialization in C++
So, there is no standard way because, simply put, because there is no way of serializing pointers and things like that. It will always be application specific.
However, you can create your own class and serialize as you want.
As for xml parsers, have you tried this one? It is extremely simple, efficient, and easy to learn. I've done basically all with it. You can even ask for a commercial license to it.
Problems while accessing Java method through XSL .'I have a java class DirectoryReader.java with a static method totalPhotos which returns a int. In my XSL I have defined a namespace: xmlns:dirReader="xalan://com.mngi.eidos.util.DirectoryReader and I am trying to access the totalPhotos method like:
<xsl:variable name="totalPhotos" select="dirReader:totalPhotos($PhotoPath)"/>
Can someone please tell me what is wrong in my approach ?
I still get the following error
ERROR: 'The first argument to the
non-static Java function 'totalPhotos'
is not a valid object reference
Either the method totalPhotos must be static, or you must first create an instance of the class and pass that as the first argument to the call.
<xsl:variable name="dr" select="dirReader:new(....)"/>
<xsl:variable name="totalPhotos" select="dirReader:totalPhotos($dr,$PhotoPath)"/>
Adjust dirReader constructor arguments to your situation
Is there a way of supplying enum values as method-args in pococapsule without resorting to factory-methods?
Let say I have a class that take an enum value in its constructor
class A
{
A(myEnum val);
}
Using Pococapsule xml configuration:
I would like to express something like this:
<bean id="A" class="A">
<method-arg type="MyEnum" value="MyEnum::Value1" />
</bean>
However, since pococapsule's basic types only includes built in types such as short, char, etc this is not possible.
How would I go about to instantiate a class A using pococapsule?
I could resort to using factory methods something like this:
MyEnum GetMyEnumValue1()
{
return MyEnum::Value1;
}
<bean id="A" class="A">
<method-arg factory-method="GetMyEnumValue1" />
</bean>
Which isn't very practical. I would have to implement a new factory method for every possible value of each and every enum used.
Some would argue that enum:s shouldn't be passed in constructors or setter methods as it is a sign of a class doing to much. Yes I agree. However, there is a lot of third party code and c++ frameworks out there that uses this style, so I need to be able to do this.
Edit:
The issue was resolved on Pococapsule's discussion forum. The work-around in this specific case was to have factory methods perform the desired action. It is not as flexible as declaring enum-use in the xml-config file, but it moved the project forward. Thanks Ke for your help.
(repost, as the XML code was filtered out in previous reply)
In C/C++ enums are able to be passed as int implicitly, therefore, you can simply have type="long" in the method-arg element.
You can also use the DSM feature to define your own extend schema that supports your specific enum (it should be similar to the user example in examples/basic-ioc/ext-schema where DSM is used to typesafely support user defined Map type).
-Ke
In C/C++ enums are able to be passed as int implicitly, therefore, you can simply do:
You can also use the DSM feature to define your own extend schema that supports your specific enum (it should be similar to the user example in examples/basic-ioc/ext-schema where DSM is used to typesafely support user defined Map type).
-Ke