My question basically is the same as this question.
I don't have enough reputation to add a comment to the OP's question. Please help
The problem I'm having is:
The SOAP web service I'm trying to call requires the header to have two elements, one containing basic header data and another with synchronisation specific data, the header that's required looks like this :
<header>
<initHeader>
<requestID></requestId>
<...some more elements>
</initHeader>
<syncHeader>
<appId></appId>
<dateTime></dateTime>
<event></event>
</syncHeader>
</header>
When generating the header using WebServiceMessageCallback (specifically during the transformation shown below), I get this:
"ERROR: 'The markup in the document following the root element must be well-formed.'"
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new StringSource(soapHeaderStr), ((SoapMessage) message).getSoapHeader().getResult());
The issue here is that the transformer expects all the elements in the header to be under one root element. But here, the header has two.
I changed the header data like this(below) and the transformer does not complain.
<header>
<myRootelement>
<initHeader>
<requestID></requestId>
<...some more elements>
</initHeader>
<syncHeader>
<appId></appId>
<dateTime></dateTime>
<event></event>
</syncHeader>
</myRootelement>
</header>
According to the above mentioned question, the OP had solved this problem by addigng a dummy root element as above and then removing it just before transforming it into the header.
I want to know how this removal of the dummy root elements is possible ? Something like this may be ? http://technology.amis.nl/2011/05/16/how-to-remove-unwanted-soap-header-elements-in-jax-ws/
I'm not quite sure how to remove a root element while keeping its children intact.
Managed to solve the problem, Here's how :
Instead of marshalling the two elements into StringResult objects and then trying to add them to the header using a the Transformer like this :
StringResult stringResult = new StringResult();
webServiceTemplate.getMarshaller().marshal(element, stringResult);
StringSource headerSource = new StringSource(stringResult.toString());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(headerSource, soapHeader.getResult());
You can marshal the two elements directly into the soap header like this :
webServiceTemplate.getMarshaller().marshal(element1,soapHeader.getResult());
webServiceTemplate.getMarshaller().marshal(element2,soapHeader.getResult());
The marshaller mentioned here is a "org.springframework.oxm.jaxb.Jaxb2Marshaller"
The element 1 and 2 above are the JAXB elements created using the generated Object factory class.
With this approach, there is no need to add dummy root elements.
Hope this helps someone out there, and thanks to Grigori.G for pointing me in the right direction !
Related
So I have a case where I need to be able to work on the actual Hyperlink element inside the body of the docx, not just the target URL or the internal/externality of the link.
As a possible additional wrinkle this hyperlink wasn't present in the docx when it was opened but instead was added by the docx4j-xhtmlImporter.
I've iterated the list of relationships here: wordMLPackage.getMainDocumentPart().getRelationshipsPart().getRelationships().getRelationship()
And found the relationship ID of the hyperlink I want. I'm trying to use an XPath query: List<Object> results = wordMLPackage.getMainDocumentPart().getJAXBNodesViaXPath("//w:hyperlink[#r:id='rId11']", false);
But the list is empty. I also thought that it might need a refresh because I added the hyperlink at runtime so I tried with the refreshXMLFirst parameter set to true. On the off chance it wasn't a real node because it's an inner class of P, I also tried getJAXBAssociationsForXPath with the same parameters as above and that doesn't return anything.
Additionally, even XPath like "//w:hyperlink" fails to match anything.
I can see the hyperlinks in the XML if I unzip it after saving to a file, so I know the ID is right: <w:hyperlink r:id="rId11">
Is XPath the right way to find this? If it is, what am I doing wrong? If it's not, what should I be doing?
Thanks
XPathHyperlinkTest.java is a simple test case which works for me
You might be having problems because of JAXB, or possibly because of the specific way in which the binder is being set up in your case (do you start by opening an existing docx, or creating a new one?). Which docx4j version are you using?
Which JAXB implementation are you using? If its the Sun/Oracle implementation (the reference implementation, or the one included in their JDK/JRE), it might be this which is causing the problem, in which case you might try using MOXy instead.
An alternative to using XPath is to traverse the docx; see finders/ClassFinder.java
Try without namespace binding
List<Object> results = wordMLPackage.getMainDocumentPart().getJAXBNodesViaXPath("//*:hyperlink[#*:id='rId11']", false);
I have created some custom actions to use inside a Magento Dataflow profile. I would like to pass in composite parameter values (arrays or dictionaries) to the action, similar to the map var you can pass to the default parser actions. I.e., I would like to do something like this:
<var name="attribute_map">
<map name="sColore"><![CDATA[colore]]></map>
<map name="sMarca"><![CDATA[marca]]></map>
<map name="sFornitore"><![CDATA[fornitore]]></map>
</var>
The variable turns out as null in this case, although, upon fiddling with the xml and skimming through the code, it seems that this pattern only works with <var name="map">. Puzzling and disappointing. I also have not been able to find even the slightest hint about the relevant xml schema in any documentation whatsoever...
Any idea on this? Thanks!
(I am working with Community Edition version 1.7.0.2)
If i understand right what you ask, you could overwrite the system/convert/profile/wizard.phtml from admin and add another section similar to existing map but the form elements should have name="gui_data[attribute_map]...[]".
Then you should overwrite the _parseGuiData method from Mage_Dataflow_Model_Profile to form the correct profile actions xml.
Hope that helps.
You can't, using the core implementation.
The var elements can only contain simple text, unless the element has the attribute name="map", in which case the profile parser will search for children map elements and use them to populate a php associative array.
The relevant code is inside the importProfileXml method of the Mage_Dataflow_Model_Convert_Profile_Collection class:
if ($varNode['name'] == 'map') {
$mapData = array();
foreach ($varNode->map as $mapNode) {
$mapData[(string)$mapNode['name']] = (string)$mapNode;
}
$container->setVar((string)$varNode['name'], $mapData);
}
To extend this behavior you should override this class with a custom (sub)class through the usual magento class override methods.
I know this doesn't exactly match the form of www.example.com/class/function/ID/, but what I want to display to the user would make more sense.
This is what I would like to do:
www.example.com/project/id/item/item_id/
So, an example would be:
www.example.com/project/5/item/198237/
And this would be the behavior:
www.example.com/project/ --> This would show a list of projects (current implementation)
www.example.com/project/5/ --> This would show a list of items on project 5 (current implementation)
www.example.com/project/5/item/ --> This wouldn't really mean anything different than the line above. (Is that bad?)
www.example.com/project/5/item/198237/ --> This would show details for item 198237.
So, each item is directly associated with one and only one project.
The only way I can think how to do this is to bloat the "project" controller and parse the various parameters and control ALL views from that "project" controller. I'd prefer not to do this, because the model and view for an "item" are truly separate from the model and view of a "project."
The only other solution (that I am currently implementing and don't prefer) is to have the following:
www.example.com/project/5/
www.example.com/item/198237/
Is there any way to build a hierarchical URL as I showed at the beginning without bloating the "project" controller?
There are 3 options, sorted by how practical they can be:
Use URI Routing. Define a regular expression that will use a specific controller/method combination for each URL.
Something like that could help you, in routes.php:
$route['project/'] = 'project/viewall';
$route['project/(.+)'] = 'project/view/$1';
$route['project/(.+)/item/'] = 'project/view/$1';
$route['project/(.+)/item/(.+)'] = 'item/view/$2';
That is, considering your controllers are item and project respectively. Also note that $n in the value corresponds to the part matched in the n-th parenthesis.
Use the same controller with (or without) redirection. I guess you already considered this.
Use redirection at a lower level, such as ModRewrite on Apache servers. You could come up with a rule similar to the one in routes.php. If you are already using such a method, it wouldn't be a bad idea to use that, but only if you are already using such a thing, and preferably, in the case of Apache, in the server configuration rather than an .htaccess file.
You can control all of these options using routes.php (found in the config folder). You can alternatively catch any of your URI segments using the URI class, as in $this->uri->segment(2). That is if you have the URL helper loaded. That you can load by default in the autoload.php file (also in the config folder).
Improving on this question:
Is it good practice to add own file in lib/Varien/Data/Form/Element folder
The accepted answer shows how to extend a Varien form element, but this will not work if you want to package it into a custom module.
What would be the proper method of extending the Varien form element in a module? A simple XML setting I'm hoping?
Update:
Thanks Vinai for the response. Although that does work, I was hoping to extend the form element somehow. My extension is using the base File form element to allow administrators to upload files to categories. So, I'm not directly adding the form elements to the fieldset myself.
I suppose it's possible to to check for the file input on my category block on the backend: Mage_Adminhtml_Block_Catalog_Category_Tab_Attributes , and then change the form element if it is 'file' to 'mycompany_file' -- but this seems like a workaround.
Is there an easier way? Thanks again Vinai.
On the Varien_Data_Form instance you can specify custom element types like this:
$fieldset->addType('custom', 'Your_Module_Model_Form_Element_Custom');
Then, add your element with
$fieldset->addField('the_name', 'custom', $optionsArray);
If you are using a form without fieldsets you can do the same on the Varien_Data_Forminstance, too.
EDIT: Expand answer because of new additional details in the question.
In the class Mage_Adminhtml_Block_Widget_Form::_setFieldset() there is the following code:
$rendererClass = $attribute->getFrontend()->getInputRendererClass();
if (!empty($rendererClass)) {
$fieldType = $inputType . '_' . $attribute->getAttributeCode();
$fieldset->addType($fieldType, $rendererClass);
}
Because of this the attribute frontend_input_renderer on the attributes can be used to specify custom element classes.
This property can be found in the table catalog_eav_attribute, and luckily enough it isn't set for any of the category image attributes.
Given this, there are several ways to apply customizaton.
One option is to simply set the element class in the table using an upgrade script.
Another would be using an observer for the eav_entity_attribute_load_after event and setting the input renderer on the fly if the entity_type_id and the input type matches.
So it is a little more involved then just regular class rewrites in Magento, but it is quite possible.
You don't necessarily need to have a file in the lib/Varien/ directory in order to extend it. If you needed to add an element to that collection, you should be able to extend one of the Elements in your app/code/local module. The answer to the question you referenced seems to also indicate this is the case. I would create your custom field, extending its highest-level function set (i.e., lib/Varien/Data/Form/Element/File.php).
If you want to override the Mage_Adminhtml_Block_Catalog_Category_Tab_Attributes block, then you should extend that block in your module and then reference the new one. You may wish to extend the block using an event observer rather than an XML rewrite, for compatibility purposes.
I have a application which allows user to make a search.
Based on the search criteria entered, a service call to DAO function is made (pattern jsp event -> interceptors -> processors -> services -> DAO -> database) and list of results is returned back which gets displayed in myView.jsp
Code as below is used to read the TO data in JSP:
<jsp:usebean id="myTO" type="com.myPackage.MyTO" scope="session"/>
and in the body something like
<%= myTo.getSomething() =%>
Each item on the list is clickable for details. So on clicking item 2 on the list, another call will be made with item 2's id to fetch more details on item 2.
Depending on type of item, the details are fetched in different TO's. e.g. Type1TO, Type2TO.
So detailed data on item is returned in one such TO.
Issue is: I am displaying the details in the same JSP. So the returnURL of the second request gets forwarded to myView.JSP
So I have put a line like
<jsp:usebean id="type1TO" type="com.myPackage.Type1TO" scope="session"/>
However this gives error during the first call of list search when above Type1TO does not yet exist. Error is something like "unable to find type1TO in scope session"
How could I solve this issue ???
Is there a way to put jsp:usebean tag in an if condition in the place where it is to be used in the body ?? Or any other solution to this ??
I am new to JSP and dealing with legacy JSP. So very advanced JSP (complex EL) might not be feasible.
The following are the usages of the <usebean>:
<jsp:useBean id=”connection” class=”com.myco.myapp.Connection” /> . In this example the bean with the id is made available either by creating or finding the existing one in the session
<jsp:useBean id=”connection” class=”com.myco.myapp.Connection”>
<jsp:setProperty name=”connection” property=”timeout” value=”33”>
</jsp:useBean>. In this example, the bean is created or found, and instatiated with the setProperty if it is being created.
<jsp:useBean id=”wombat” type=”my.WombatType” scope=”session”/>. In this example the existing bean is found and made available with the given type.
If translated to Servlet, your first code snippet will look like:
getAttribute("myTO");
Whether to use a single attribute or 'multiple attributes with if-else logic' depends on your particular case. Without understanding your particular situation, I can see the following options:
Option 1
Wherever you are setting myTO attribute, ensure you set the value to the same variable, so that you don't have to use if-else logic in jsp.
Option 2
Use scripts
<%
com.myPackage.MyTO toObject = session.getAttribute("myTo");
if (toObject == NULL) {
toObject = session.getAttrbute("type1TO");
}
%>