Including a Static XSD in a Web Form

cancel
Showing results for 
Search instead for 
Did you mean: 

Including a Static XSD in a Web Form

Member II
0 37 2,733
Since their inception, Alfresco WCM Web Forms have supported an inclusion mechanism based on the standard XML Schema include and import constructs.  Originally this mechanism read the included assets from the Web Project where the user was creating the content, but since v2.2SP3 the preferred mechanism has been to reference a Web Script instead (in fact the legacy mechanism may be deprecated in a future release).



One question that this new approach raises is how to support inclusion of static XSDs, as Web Scripts are inherently dynamic and introduce some unnecessary overhead for the simple static case.  The good news is that Alfresco ships with a Web Script that simply reads a file from the repository and returns its contents:

/api/path/content{property}/{store_type}/{store_id}/{path}?a={attach?}





An example usage is:

/api/path/content/workspace/SpacesStore/Company Home/Data Dictionary/Presentation Templates/readme.ftl





Using the Web Script inclusion mechanism for Web Forms, we can use this Web Script to include or import any XSD file stored in the DM repository.  For example, if we have a file called 'my-include.xsd' in the 'Company Home' space that contains the following content:

<?xml version='1.0'?>

<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'

           xmlns:alf='http://www.alfresco.org/'

           targetNamespace='http://www.alfresco.org/'

           elementFormDefault='qualified'>

  <xs:complexType abstract='true' name='IncludedComplexType'>

    <xs:sequence>

      <xs:element name='Title'

                  type='xs:normalizedString'

                  minOccurs='1'

                  maxOccurs='1' />

      <xs:element name='Summary'

                  type='xs:string'

                  minOccurs='0'

                  maxOccurs='1' />

      <xs:element name='Keyword'

                  type='xs:normalizedString'

                  minOccurs='0'

                  maxOccurs='unbounded' />

    </xs:sequence>

  </xs:complexType>

</xs:schema>





We could include it into a Web Form XSD using an include statement such as the following:

<?xml version='1.0'?>

<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'

           xmlns:alf='http://www.alfresco.org/'

           targetNamespace='http://www.alfresco.org/'

           elementFormDefault='qualified'>

  <xs:include schemaLocation='webscript://api/path/content/workspace/SpacesStore/Company Home/my-include.xsd?ticket={ticket}' />

  <xs:complexType name='MyWebFormType'>

    <xs:complexContent>

      <xs:extension base='alf:IncludedComplexType'>

        <xs:sequence>

          <xs:element name='Body'

                      type='xs:string'

                      minOccurs='1'

                      maxOccurs='1' />

        </xs:sequence>

      </xs:extension>

    </xs:complexContent>

  </xs:complexType>

  <xs:element name='MyWebForm' type='alf:MyWebFormType' />

</xs:schema>





This is clearly faster and easier than developing a custom Web Script to either emit the XML Schema shown above, or to return the contents of a specific XSD file from the repository!



This approach also provides a solution to another question: how does one neatly package up a Web Form, along with all of its dependencies, ready for deployment to another Alfresco environment?



By storing included XSD files in Company Home > Data Dictionary > Web Forms, we give ourselves the option to package up the entire Web Forms space as an ACP file and deploy that ACP file to any other Alfresco environment, knowing that we've captured not only all of the Web Forms in the source environment, but all dependent XSD files as well.

37 Comments
Active Member
Hi,



I tried this and its working for xsd schema.



But when I try to use the same pattern in xsl:import to import global xsl templates for the web forms it doesnt work.

I am adding this to the xsl that is associated to the web form







I also tried include







It gives error

Error generating rendition using Global_CRCnetBASE_landing_page.xsl: javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: ElemTemplateElement error: substring-after-last
Member II
Kalpesh, xsl:imports aren't available from within XSL-backed renditioning templates but that would make a good enhancement request.  I would also encourage you to investigate Freemarker-backed renditioning templates, as it's a more flexible templating language and (via a forge project) supports inclusion of Web Scripts.
Active Member
Including the webscripts in webform,

It will work only with the xsd files ? as we have here in the example including my-include.xsd (or) else we can also add webscripts which has *.xml file  and response template *.ftl (or) /sample/ - webscript url, which one do we need to specify in the include to get the webscripts in webforms?
Member II
Saran, you can xs:include or xs:import the response from any Web Script, including custom Web Scripts that dynamically generate XSD.  The only requirement is that the output from the Web Script is a valid XML Schema - that's a requirement of the xs:include / xs:import mechanisms.



And just to clarify, this blog post illustrates the simpler use case of xs:including or xs:importing a static XSD file, without having to develop a custom Web Script (as a Web Script suitable for this purpose is included in Alfresco).  It should be straight forward to extrapolate the custom Web Script use case from this example however, as the only additional moving part is the custom Web Script (and Web Script development is documented in detail elsewhere).
Active Member
This is very useful for an XSD standpoint , I've used webscripts to populate dynamic XSDs, and they seemed to work very well.

Is there a way to call webscripts within an XSL file also?
Member II
agibson, as I mentioned to Kalpash:

'xsl:imports aren’t available from within XSL-backed renditioning templates but that would make a good enhancement request. I would also encourage you to investigate Freemarker-backed renditioning templates, as it’s a more flexible templating language and (via a forge project) supports inclusion of Web Scripts.'

Active Member
Oops , thanks for the info , Here is what I found , http://forge.alfresco.com/scm/?group_id=211



Having trouble with the anonymous access of the subversion repository though is it still available?
Member II
Yeah I have a vague recollection that the forge doesn't allow anonymous SVN checkouts (despite suggesting that they are allowed).  It's free to register though, so I'd suggest registering and seeing if you can checkout then.
Active Member
Peter , do you have any examples of using the Freemarker WSI , i.e proper syntax to include webscript , also I've added the freemarker wsi to my alfresco.war , but don't really know where to go from there. Any help appreciated
Member II
agibson, there's an example included in the source code on the forge project.
Active Member
Thanks Peter,



Sorry, I visited this page after a month time.

Thanks for all the good work and creative samples that help us to reuse it in projects.
Active Member
Just to report back on some of my findings , I did get the Freemarker WSI project to work with a simple freemarker page and webscript, considering I am on 3.1 there were a few updates to the java code and spring configuration to get it all working .....It did not however work for XSL inclusion in Web forms, and I haven't had time to figure out exactly why.
Member II
agibson, the Freemarker WSI project is not intended to provide an inclusion mechanism for XSL templates - its sole purpose is to provide a way to include the output from a Web Script in a Freemarker template.
Active Member
Sorry I mispoke , I meant to say ....



*It did not however work for Freemarker template inclusion in Web forms, and I haven’t had time to figure out exactly why.
Member II
Ah ok.  Do you have an account on the Alfresco forge?  If so let me know what it is and I'll add you as a committer to the freemarker-wsi project so that if/when you find out what's breaking you can commit your changes.
Active Member
Hi Peter ,



The WSI is working in Web Scripts , but it does not appear to work in Web forms. I have updated the code to work with Enterprise 3.1 , if you want to create a branch I can commit to it .... my Alfresco forge accout is agibson
Active Member
Hi Peter,



I'm attempting to have a XSD use this method to include a XSD that, itself has includes.  That second include isn't working.



Thoughts on whether trying to build something like that is a good idea or bad idea?



Thanks,

Karl
Active Member
Thank you so much for this info Peter.  Very useful!!
Active Member
Ey Peter, quick question, I tried the example you used in this post, but nothing happens! Smiley Frustrated



I create the my-include.xsd file copy pasting the contents of the example, and uploadead it to My Company Home, I create a web from using the same data above (copy paste, again), then when I try to create content with that webform, nothing happens! An empty webform is displayed Smiley Sad



Can you help me?
Member II
I suspect the problem is that the blog software replaces various characters (most noticeably double quotes) with UTF alternatives that aren't valid in XML Schemas, which prevents the Web Form from loading properly.
Active Member
Hi Peter,



Firstly, this is a great post. Thank You.



I tried this example in Alfresco Community 3.2r2. I have uploaded my-include.xsd in Company Home space. Then I also created the Web Form using your Web Form xsd. However, when I tried to create content using the Web Form in my Web Project, I get the following error:





'is an invalid character. org.alfresco.web.forms.FormProcessor$ProcessingException: org.alfresco.web.forms.xforms.FormBuilderException: error parsing schema: at line 8 column 52: src-resolve: Cannot resolve the name 'alf:IncludedComplexType' to a(n) 'type definition' component.  '



Please help.



Thanks.
Active Member
sorry. This is the error I get when I tried to create content using the Web Form in my Web Project:



'org.alfresco.web.forms.FormProcessor$ProcessingException: org.alfresco.web.forms.xforms.FormBuilderException: error parsing schema: at line 8 column 52: src-resolve: Cannot resolve the name ‘alf:IncludedComplexType’ to a(n) ‘type definition’ component. ”
Member II
Patricia, did you copy the code from this blog post into the XSD files directly?  If so the problem is likely related to the blog software reformatting some of the text with characters that aren't valid in XML (non-breaking whitespace characters, '66' and '99' double quotes and the like).
Active Member
Thanks Peter for replying.



I copied and paste the code in Eclipse Xml Schema Editor, then fixed the double quotes and stuff in the editor before uploading the xsd files into Alfresco.
Active Member
What about nested dependencies? Or included schemas that also need to include other ones?
Member II
Jose, Alfresco does not expand nested webscript:// includes.
Active Member
Hi,



Your example works fine but now I want to include a schema from my project sandbox. When I construct the link I believe is appropriate, I get the error. Here is output from the webscript:

*****

The Web Script /alfresco/service/api/path/content/avm/myproject--admin/www/avm_webapps/ROOT/b.xsd has responded with a status of 404 - Not Found.

404 Description: Requested resource is not available.

Message: 08200048 Unable to find ObjectPathReference[storeRef=avm://myproject--admin,path=/Company Home/www/avm_webapps/ROOT/b.xsd]

*****

Somehow, web script assumes 'Company Home' as the root of the store... or am I doing something wrong?
Member II
hmmm..........the insertion of 'Company Home' into the NodeRef does look highly suspicious.  I'd suggest creating a bug report in the Alfresco JIRA, and include reproduction steps, expected result and actual result.  If you post the JIRA ticket # back here I can also take a look at it.



That said, normally it's not a good idea to place a Web Form XSD in the Web Project itself, since then it becomes part of the content of that Web Project (meaning it gets deployed out to the delivery tier etc.).  This confuses what should be a clear separation between assets that modify the behaviour of the authoring tool (e.g. Web Form XSDs) and the assets that are actually under management.  In fact this is a large part of the reason Alfresco WCM moved away from including XSD files via the virtualisation server in 2.2 - that was not a very well thought out approach.
Active Member
Thanks for your reply, I reported the issue, ALF-4877.



Indeed, it is not the cleanest approach but I gues the only possible in web forms. I have a form where a customer can manage some item. Item may have categories which are managed in another web form. The only and obvious (to me) solution is to add a transformation to the latter web form that will take user supplied categories and create a schema with enumeration type. This category schema will then be included into item schema.



There is no danger in exporting this schema to the deployment target - it will not be used as no component there is aware of it. However, the fact that a user may inadvertantly delete it from web project may require a new web script that will take a default within web form space if target is not found. I think I am going to make that script now ;-)
Member II
Thanks Nikola - here's a direct link to ALF-4877 in case anyone else is affected by this and wants to vote and/or comment on it.
Active Member
First of all I want to thank you for this great post. This works fine.

I have created dynamic xsd which calls webscript. I have so many fields in my form and for around 60% of the fields the webscript is called.

Because of this the peformance is not good.

I want to divide this xsd in to two in a manner when I click on create content the first xsd should be loaded and when I click on Next the second one.

How can I achieve this?
Member II
Rajesh, progressive loading of forms is not currently supported by Web Forms, but would be a good enhancement request (which can be raised in the Alfresco JIRA).
Active Member
@rajesh



I am also trying to accomplish something similar. The content becomes too long for content editors to edit. I would prefer to split the xsd into content xsd and metadata xsd.



Were you able to find a solution?



thanks
Active Member
I was able to accomplish the dynamic loading of an xsds elements by creating an external web service that builds the included xml.  The scenario is as follows:



Have one form as a exampleTemplate.  It would have a drop down that needs to contain dynamicly loaded values from a database external to alfresco, as well as some other static entry fields.



I created a restful service deployed on my ESB, can be anywhere, that when called queries the database and then builds an xsd as a string to be returned.



I then use the



<xsd:include to call the service as a dynamically built included xsd into my main xsd. 



This is working great.
Member II
Nice!  Yeah loading of dynamic XSDs via <xs:include> / <xs:import> is also possible, although a little more involved than the simple static case described above.  Thanks for sharing your solution Eric!
Active Member
[…] I hope this proves useful for beginner Alfresco developers. Incidentally, Peter Monks has a nice introduction to using includes as part of an Alfresco Web Form definition. Also, here’s a well-presented discussion on the […]
Active Member
The post is handsomely written. I have bookmarked you for keeping abreast with your new posts.

sap grc online training

sap tm online training

sap hr/hcm online training