Page 1 of 1
Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Tue Feb 21, 2017 6:54 pm
by Johann
Hi everyone,
In the Author Component, I try to test
Configuring Proposed Values in the Context that the Content Completion was Invoked
from
https://www.oxygenxml.com/doc/versions/ ... -proposals
An EE or PE version of SAXON is required to perform this configuration.
Is there a way to use another XSLT Processor in the Author Component instead of SAXON ?
Thank your for your response,
Johann
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Feb 23, 2017 4:53 pm
by alex_jitianu
Hi Johann,
In theory the XSLT should run just fine with Saxon-HE (which is available in the Author Component) as long as the XSLT doesn't use any functionality available only in the PE/EE versions. If you would need access to the element for which the CC was invoked, you will run into this issue (because saxon:eval() is not available in the HE version).
Code: Select all
<xsl:variable name="propertyElement"
select="saxon:eval(saxon:expression($contextElementXPathExpression, ./*))"/>
Unfortunately there is no workaround for this other than using the Java API instead and implementing a
SchemaManagerFilter.
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Jul 19, 2019 7:21 pm
by Isabelle
Hello Everyone,
I try to implement this solution in our ContentCompletionConfigurator java class with Saxon PE.
But when I execute this :
Code: Select all
ProfessionalTransformerFactory fac = new ProfessionalTransformerFactory();
I get this error :
Code: Select all
java.lang.SecurityException: class "net.sf.saxon.Configuration$ApiProvider"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(ClassLoader.java:898) ~[na:1.8.0_112]
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:668) ~[na:1.8.0_112]
at java.lang.ClassLoader.defineClass(ClassLoader.java:761) ~[na:1.8.0_112]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_112]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_112]
at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_112]
at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_112]
at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_112]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_112]
at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_112]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_112]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_112]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_112]
at com._4dconcept.adam.author.plugin.contentCompletion.ContentCompletionConfigurator.updateCCConfigurationFile(ContentCompletionConfigurator.java:84) ~[classes/:na]
at com._4dconcept.adam.author.plugin.views.S1000DDownloaderOpenerWorker.doBeforeWork(S1000DDownloaderOpenerWorker.java:30) ~[classes/:na]
at com._4dconcept.adam.author.plugin.views.AbstractDownloaderOpenerWorker.doInBackground(AbstractDownloaderOpenerWorker.java:66) ~[classes/:na]
at javax.swing.SwingWorker$1.call(SwingWorker.java:295) [na:1.8.0_112]
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) [na:1.8.0_112]
at java.util.concurrent.FutureTask.run(FutureTask.java) [na:1.8.0_112]
at javax.swing.SwingWorker.run(SwingWorker.java:334) [na:1.8.0_112]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_112]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_112]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112]
It seems that it does not take the good
net.sf.saxon.Configuration class.
I have checked with
mvn dependency:tree, and I am sure only Saxon PE is called.
Would there be a conflict with oxygen jars?
Have you ever encountered this mistake ?
If yes, how did you solve it ?
Thanks for any help.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Mon Jul 22, 2019 8:25 am
by Radu
Hi Isabelle,
The Author Component SDK also comes with a Saxon HE JAR library called something like "oxygen-patched-saxon-9". So adding an extra Saxon 9 library directly to the classpath will not work.
You can either use our API to create a Saxon HE transformer:
Code: Select all
PluginWorkspaceProvider.getPluginWorkspace().getXMLUtilAccess().createXSLTTransformer(styleSource, new URL[0], XMLUtilAccess.TRANSFORMER_SAXON_HOME_EDITION)
or if you have a commercial license for Saxon PE and you explicitly want to use Saxon PE with our component you will probably need to load the Saxon PE libraries on a separate Java class loader using Java reflection so that they do not interfere with ours.
Regards,
Radu
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Mon Jul 22, 2019 11:34 am
by Isabelle
Hello Radu,
As Alex said, we can not use Saxon HE to implement your solution because saxon:eval() is not available in the HE version.
It is not possible to "exclude" oxygen-patched-saxon-9 with Maven ?
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Mon Jul 22, 2019 12:22 pm
by Radu
Hi Isabelle,
Our code absolutely needs the "oxygen-patched-saxon-9" in its current form, otherwise it might break in unexpected places.
Two possible workarounds for you:
1) XSLT 3.0 added the xsl element xsl:evaluate:
https://stackoverflow.com/questions/472 ... te-example
and using it should work even with Saxon HE.
2) Do not add your Saxon JAR library to the Maven class path, place it (and its commercial license) in another folder, create from the code an URLClassLoader which loads the JAR library and then license folder, then use that class loader to load the classes you are interested in and work with them using Java reflection.
Regards,
Radu
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Wed Jul 24, 2019 6:34 pm
by Isabelle
Hi Radu,
I tried to create from the code an URLClassLoader which loads the JAR library, and then use that class loader to load classes I need and work with them using Java reflection.
Here is my code
Code: Select all
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SaxonPEUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(SaxonPEUtils.class);
private static final String SAXON_PE_PATH = "C:/apps/saxon-pe/saxon9pe.jar";
public static Object newSaxonPETransformer(Source xslt) {
Object transformer = null;
try {
File externalJar = new File(SAXON_PE_PATH);
if(externalJar.exists()) {
URLClassLoader saxonClassLoader = new URLClassLoader(new URL[]{externalJar.toURI().toURL()}, ClassLoader.getSystemClassLoader());
Class<?> classToLoad = saxonClassLoader.loadClass("com.saxonica.config.ProfessionalTransformerFactory");
Constructor<?> conTest = classToLoad.getConstructor();
Object proTransformerFactory = conTest.newInstance();
Method method = proTransformerFactory.getClass().getMethod("newTransformer", Source.class);
transformer = method.invoke(proTransformerFactory, xslt);
} else {
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
transformer = TransformerFactory.newInstance().newTransformer();
LOGGER.error("Saxon PE not found in " + externalJar.getAbsolutePath() + ". Saxon HE TransformerFactory.newTransformer() provided instead.");
}
} catch (ClassNotFoundException | IllegalAccessException |InvocationTargetException | InstantiationException | NoSuchMethodException | MalformedURLException | TransformerException e) {
LOGGER.error(e.getMessage(), e);
}
return transformer;
}
}
Even if I specify an external class loader as parent
ClassLoader.getSystemClassLoader(), it does not work because it still looking in
oxygen-patched-saxon-9he-21.1.0.2.jar.
[SwingWorker-pool-8-thread-2] ERROR c._.a.a.plugin.utils.SaxonPEUtils - SYSTEM - null
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_112]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_112]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_112]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_112]
at plugin.utils.SaxonPEUtils.newSaxonPETransformer(SaxonPEUtils.java:30) ~[classes/:na]
at plugin.contentCompletion.ContentCompletionConfigurator.updateCCConfigurationFile(ContentCompletionConfigurator.java:75) [classes/:na]
at plugin.views.OpenerWorker.doBeforeWork(OpenerWorker.java:30) [classes/:na]
at plugin.views.AbstractOpenerWorker.doInBackground(AbstractOpenerWorker.java:66) [classes/:na]
at javax.swing.SwingWorker$1.call(SwingWorker.java:295) [na:1.8.0_112]
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) [na:1.8.0_112]
at java.util.concurrent.FutureTask.run(FutureTask.java) [na:1.8.0_112]
at javax.swing.SwingWorker.run(SwingWorker.java:334) [na:1.8.0_112]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_112]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_112]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112]
Caused by: java.lang.NoSuchMethodError: com.saxonica.config.ProfessionalConfiguration.internalSetBooleanProperty(Lnet/sf/saxon/lib/Feature;Ljava/lang/Object;)V
at com.saxonica.config.ProfessionalConfiguration.setConfigurationProperty(ProfessionalConfiguration.java:265) ~[na:na]
at com.saxonica.config.ProfessionalConfiguration.setConfigurationProperty(ProfessionalConfiguration.java:254) ~[na:na]
at net.sf.saxon.Configuration.init(Configuration.java:651) ~[oxygen-patched-saxon-9he-21.1.0.2.jar:na]
at net.sf.saxon.Configuration.<init>(Configuration.java:432) ~[oxygen-patched-saxon-9he-21.1.0.2.jar:na]
at com.saxonica.config.ProfessionalConfiguration.<init>(ProfessionalConfiguration.java:133) ~[na:na]
at com.saxonica.config.ProfessionalTransformerFactory.<init>(ProfessionalTransformerFactory.java:25) ~[na:na]
... 15 common frames omitted
I do not understand what I miss, any idea ?
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Jul 25, 2019 8:41 am
by Radu
Hello Isabelle,
Problem with class loaders (your custom URLClassLoader in this case) is that they prefer to return the classes from the super class loader if they have already been loaded.
So in various places in Oxygen we use a class loader we call LateDelegationClassLoader which prefers to load classes from its JAR libraries instead of falling back on the parent class loader. I'm pasting below how the contents of our late delegation class loader look like:
Code: Select all
public class LateDelegationClassLoader extends URLClassLoader {
public LateDelegationClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
@Override
public URL getResource(final String name) {
return AccessController.doPrivileged(new PrivilegedAction<URL>() {
/**
* @see java.security.PrivilegedAction#run()
*/
@Override
public URL run() {
// Try locally.
URL url = findResource(name);
if (url == null) {
// Delegate to super.
url = LateDelegationClassLoader.super.getResource(name);
}
return url;
}
});
}
@Override
protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
if(delegateToParent(name)){
// Delegate to super.
c = super.loadClass(name, false);
} else {
// Try locally
try {
c = findClass(name);
} catch (ClassNotFoundException e) {
// Delegate to super.
c = super.loadClass(name, false);
}
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
protected boolean delegateToParent(String className) {
if(className.equals(getClass().getName())){
//EXM-36639 Prefer having a single class loaded usually in the base class loader.
//In this way we can use instanceof for example.
return true;
}
return className.startsWith("java.") || className.startsWith("javax.swing.")
// EXM-16043 XHive bootstrap needs xbean.jar which redefines the org.w3c.dom package.
|| className.startsWith("org.w3c.dom.")
//EXM-24640 The unmarshalling in
//ro.sync.xml.uriattributes.URIAttributesRepository.loadRepository(URL)
//fails if the xml-apis.jar is preferred to resolve these interfaces.
|| className.startsWith("javax.xml.datatype.")
|| className.startsWith("javax.xml.parsers.")
|| className.startsWith("javax.xml.transform.")
|| className.startsWith("javax.xml.validation.")
// EXM-24901 Documentum needs this package.
|| className.startsWith("javax.xml.namespace.")
|| className.startsWith("org.xml.sax.")
// EXM-25938 XMLInputFactory requires com.ctc.wstx.stax.WstxInputFactory
// so is best to use the interfaces from the JRE.
|| className.startsWith("javax.xml.stream.")
// EXM-28502: JUnit needs the annotations to be loaded on the default
// classloader.
|| className.startsWith("org.junit.");
}
/**
* @see java.net.URLClassLoader#getPermissions(java.security.CodeSource)
*/
@Override
protected PermissionCollection getPermissions(CodeSource codesource) {
PermissionCollection perms = new java.security.Permissions();
perms.add(new AllPermission());
return perms;
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
Enumeration<URL> myResources = findResources(name);
Enumeration<URL> superResources = super.getResources(name);
if(myResources == null || !myResources.hasMoreElements()) {
return superResources;
} else {
//Prefer to return my resources as the first ones.
LinkedHashSet<URL> resources = new LinkedHashSet<URL>();
while(myResources.hasMoreElements()) {
resources.add(myResources.nextElement());
}
if(superResources != null) {
while(superResources.hasMoreElements()) {
URL url = superResources.nextElement();
if(! resources.contains(url)) {
resources.add(url);
}
}
}
return new Vector(resources).elements();
}
}
}
Regards,
Radu
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Jul 25, 2019 4:46 pm
by Isabelle
Hi Radu,
Thanks for your feedback.
I did not know about that fact.
I have integrated your class and it works fine now.
Thanks again.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Jul 26, 2019 3:11 pm
by Isabelle
Hello,
Thanks to you, we can compile XSL with Saxon PE in java but we still have issue.
We try to implement
Configuring Proposed Values in the Context that the Content Completion was Invoked
that we find here
https://www.oxygenxml.com/doc/versions/ ... -proposals.
But when we launch our application and call content completion on an xml element, we have these error :
Code: Select all
60045 ERROR [ AWT-EventQueue-0 ] ro.sync.contentcompletion.xml.extensibility.values.g - javax.xml.transform.TransformerConfigurationException: E Errors were reported during stylesheet compilation
F Cannot find a 2-argument function named {http://saxon.sf.net/}expression(). Saxon extension functions are not available under Saxon-HE at line 18 and column 83
javax.xml.transform.TransformerConfigurationException: E Errors were reported during stylesheet compilation
F Cannot find a 2-argument function named {http://saxon.sf.net/}expression(). Saxon extension functions are not available under Saxon-HE at line 18 and column 83
at ro.sync.exml.workspace.b.b.d.d(Unknown Source)
at ro.sync.exml.workspace.b.b.d.c(Unknown Source)
at ro.sync.exml.workspace.b.b.d.createXSLTTransformer(Unknown Source)
at ro.sync.exml.workspace.b.b.d.createXSLTTransformer(Unknown Source)
at ro.sync.contentcompletion.xml.extensibility.values.g.getValues(Unknown Source)
at ro.sync.contentcompletion.xml.extensibility.values.b.filterAttributeValues(Unknown Source)
at ro.sync.contentcompletion.xml.gb.oyr(Unknown Source)
at ro.sync.contentcompletion.xml.db.i(Unknown Source)
at ro.sync.contentcompletion.xml.y.rgs(Unknown Source)
at ro.sync.contentcompletion.t.rgs(Unknown Source)
at ro.sync.contentcompletion.editor.k.vwl(Unknown Source)
at ro.sync.contentcompletion.editor.k.processKeyEvent(Unknown Source)
at ro.sync.contentcompletion.editor.s.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Component.java:6310)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:806)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1074)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:945)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:771)
at java.awt.Component.dispatchEventImpl(Component.java:4760)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Even if we have compiled our content completion with saxon pe, it calls saxon HE when it executes
Code: Select all
<match elementName="property" attributeName="value">
<xslt href="get_values.xsl" useCache="false" action="replace"/>
</match>
Any ideas how to correct it ?
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Tue Aug 06, 2019 1:14 pm
by alex_jitianu
Dear Isabelle,
You should remove this block from within the content completion configuration file:
Code: Select all
<match elementName="property" attributeName="value">
<xslt href="get_values.xsl" useCache="false" action="replace"/>
</match>
No matter what you do, this XSLT will be executed with the built-in Saxon HE. What you need to do is to implement your own
SchemaManagerFilter. In its
filterAttributeValues method you will execute the XSLT with your own Saxon-PE processor. The XSLT needs some external parameters that you can obtain and pass like this:
Code: Select all
/**
* @see ro.sync.contentcompletion.xml.SchemaManagerFilter#filterAttributeValues(java.util.List, ro.sync.contentcompletion.xml.WhatPossibleValuesHasAttributeContext)
*/
@Override
public List<CIValue> filterAttributeValues(List<CIValue> attributeValues,
final WhatPossibleValuesHasAttributeContext context) {
((net.sf.saxon.jaxp.TransformerImpl) transformer).setInitialTemplate("start");
// Give parameters. systemID and location path.
transformer.setParameter("documentSystemID", context.getSystemID());
String contextXPathExpression = context.computeContextXPathExpression();
if (contextXPathExpression != null) {
transformer.setParameter("contextElementXPathExpression", contextXPathExpression);
}
transformer.transform(null, outputTarget);
Once you have this class, you pack it into a Jar, you put the Jar inside the Classpath of the framework and you specify the Schema Manager in the
Extensions tab.
Please let me know if you need any additional details.
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Aug 08, 2019 7:51 pm
by Isabelle
Hello Alex,
Thanks a lot for your help.
It finally works.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Aug 08, 2019 8:38 pm
by Isabelle
Hello Alex,
As I said earlier, it works fine, but only on saved document, not on in worked / unsaved document.
Each time I asked for content completion, it used previous saved value or don't find new values.
Do you have any workaround for that ?
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Aug 09, 2019 3:16 pm
by alex_jitianu
Hello Isabelle,
If I understand it correctly, the XSLT file processes the saved version of the file, instead of the unsaved snapshot from the editor, right? If that's the case, then the fix is to set an URIResolver that will get the content from the editor, like this:
Code: Select all
URIResolver uriResolver = PluginWorkspaceProvider.getPluginWorkspace().getXMLUtilAccess().getURIResolver();
transformer.setURIResolver(uriResolver);
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Aug 09, 2019 4:03 pm
by Isabelle
Hello Alex,
Thanks for your answer.
I tried to implement it this way:
Code: Select all
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
Source quomXslt = new StreamSource(ccSpecificCCValueConfigXslFile);
URIResolver uriResolver = PluginWorkspaceProvider.getPluginWorkspace().getXMLUtilAccess().getURIResolver();
Transformer quomTransformer = (Transformer) SaxonPEManager.getInstance().newSaxonPETransformer(quomXslt, "start");
quomTransformer.setURIResolver(uriResolver);
quomTransformer.setParameter("documentSystemID", context.getSystemID());
String contextXPathExpression = context.computeContextXPathExpression();
if (contextXPathExpression != null) {
quomTransformer.setParameter("contextElementXPathExpression", contextXPathExpression);
}
quomTransformer.transform(null, new StreamResult(ccSpecificCCValueConfigXmlFile));
But it still does not work.
Did I miss something ?
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Aug 09, 2019 4:12 pm
by alex_jitianu
Hello Isabelle,
To make sure I understand the situation correctly, the XSLT file processes the saved version of the file, instead of the unsaved snapshot from the editor, right?
The code looks O.K. Can you send me the zipped plugin on
support@oxygenxml.com so I can reproduce the issue myself and look for a fix? After I finish my investigation, I will remove it from my system.
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Aug 09, 2019 4:18 pm
by Isabelle
Hello Alex,
You understand the situation correctly.
It never process the unsaved snapshot from the editor.
I don't know if I can send to you the plugin like that.
I will ask to my colleague, and let you know as soon as possible.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Tue Sep 24, 2019 1:41 pm
by Isabelle
Hi Everyone,
I have just send to
support@oxygenxml.com all relevant files in order to have your help to solve our problem.
I can't send you our application, sorry, but I tried to send you all you need.
Here is a test case :
Code: Select all
<quantity quantityType="qty05">
<quantityGroup quantityGroupType="minimum">
<quantityValue quantityUnitOfMeasure="um51">6.4</quantityValue>
<quantityValue quantityUnitOfMeasure="lbf.ft">47.2</quantityValue>
</quantityGroup>
</quantity>
We want to filter
quantityUnitOfMeasure attribute regarding the value of
quantityType attribute.
Thanks,
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Sep 26, 2019 8:35 am
by alex_jitianu
Dear Isabelle,
Thank you for taking the time to send us all those resources. It turns out that the API
URIResolver doesn't pass though the opened editors, like I initially expected. Sorry about that... Luckily there is enough API available so that you can extend this behavior. Something like this:
Code: Select all
private URIResolver creteResolver(String editorSystemId) {
final URIResolver uriResolver = PluginWorkspaceProvider.getPluginWorkspace().getXMLUtilAccess().getURIResolver();
return new URIResolver() {
@Override
public Source resolve(String href, String base) throws TransformerException {
if (editorSystemId.equals(href)) {
// Check if the file is opened inside an editor.
WSEditor editorAccess = PluginWorkspaceProvider.getPluginWorkspace().getEditorAccess(new URL(editorSystemId), PluginWorkspace.MAIN_EDITING_AREA);
if (editorAccess != null) {
Reader reader = editorAccess.createContentReader();
return new StreamSource(reader, editorSystemId);
}
}
return uriResolver.resolve(href, base);
}
};
}
Let me know how it goes!
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Sep 26, 2019 3:31 pm
by Isabelle
Hello Alex,
It works fine now !
Thanks a lot.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Tue Jan 18, 2022 11:30 am
by Isabelle
Hi all,
Is this always true ?
alex_jitianu wrote: ↑Thu Feb 23, 2017 4:53 pm
In theory the XSLT should run just fine with Saxon-HE (which is available in the Author Component) as long as the XSLT doesn't use any functionality available only in the PE/EE versions. If you would need access to the element for which the CC was invoked, you will run into this issue (because saxon:eval() is not available in the HE version).
Code: Select all
<xsl:variable name="propertyElement"
select="saxon:eval(saxon:expression($contextElementXPathExpression, ./*))"/>
Unfortunately there is no workaround for this other than using the Java API instead and implementing a
SchemaManagerFilter.
Or can we use now your version of saxon to do
saxon:eval query in 24.0.0.2 ?
If not, is it safe to exclude
com.oxygenxml:oxygen-patched-saxon-9he:jar:24.0.0.2 thanks to maven to avoid ClassLoader issues ?
Thanks.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Wed Jan 19, 2022 6:01 pm
by alex_jitianu
Hello,
You can use xsl:evaluate from XSLT 3.0 which is supported by Saxon HE. The XSLT will look like this:
Code: Select all
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/"
exclude-result-prefixes="xs"
version="3.0">
<xsl:param name="documentSystemID" as="xs:string"></xsl:param>
<xsl:param name="contextElementXPathExpression" as="xs:string"></xsl:param>
<xsl:template name="start">
<xsl:apply-templates select="doc($documentSystemID)"/>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="propertyElement" as="element()">
<xsl:evaluate xpath="$contextElementXPathExpression" context-item="./*" as="element()"></xsl:evaluate>
</xsl:variable>
<items>
<xsl:if test="$propertyElement/@name = 'color'">
<item value='red'/>
<item value='blue'/>
</xsl:if>
<xsl:if test="$propertyElement/@name = 'shape'">
<item value='rectangle'/>
<item value='square'/>
</xsl:if>
</items>
</xsl:template>
</xsl:stylesheet>
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Wed Jan 19, 2022 6:32 pm
by Isabelle
Hi Alex,
Thanks for your answer.
I tried this :
Code: Select all
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/"
exclude-result-prefixes="xs"
version="3.0">
<xsl:param name="documentSystemID" as="xs:string"/>
<xsl:param name="contextElementXPathExpression" as="xs:string"/>
<xsl:template name="start">
<xsl:apply-templates select="doc($documentSystemID)"/>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="propertyElement" as="element()">
<xsl:evaluate xpath="$contextElementXPathExpression" context-item="./*" as="element()"></xsl:evaluate>
</xsl:variable>
<items>
<xsl:if test="$propertyElement/ancestor::quantity/@quantityType = 'qty52'">
<item value='F'/>
<item value='pF'/>
<item value='uF'/>
</xsl:if>
<xsl:if test="$propertyElement/ancestor::quantity/@quantityType = 'qty56'">
<item value='Wb'/>
<item value='mWb'/>
<item value='uWb'/>
</xsl:if>
<xsl:if test="$propertyElement/ancestor::quantity/@quantityType = 'qty60'">
<item value='F/m'/>
<item value='uF/m'/>
</xsl:if>
</items>
</xsl:template>
</xsl:stylesheet>
But I get this error
Code: Select all
net.sf.saxon.trans.XPathException: net.sf.saxon.trans.XPathException: xsl:evaluate is not available in this configuration
at net.sf.saxon.expr.ErrorExpression.evaluateItem(ErrorExpression.java:138) ~[oxygen-patched-saxon-9he-24.0.0.2.jar:?]
Did I miss something ?
Thanks,
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Jan 20, 2022 11:32 am
by alex_jitianu
Hi Isabelle,
I'm sorry about that, but it seems
xsl:evaluate was introduced in Saxon HE 10 which we hope to integrate in Oxygen 24.1 (to be released in March). The current version of Oxygen bundles Saxon 9.9 in which
xsl:evaluate is only available in the PE distribution. That being said, I think the only way is to implement a custom
SchemaManagerFilter. The
WhatPossibleValuesHasAttributeContext object that comes on the
SchemaManagerFilter#filterAttributeValues() callback has all the API that you need:
-
computeContextXPathExpression()
-
executeXPath()
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Jan 21, 2022 9:06 pm
by Isabelle
Hi Alex,
Thanks for the feedback.
alex_jitianu wrote: ↑Thu Jan 20, 2022 11:32 am
it seems
xsl:evaluate was introduced in Saxon HE 10 which we hope to integrate in Oxygen 24.1 (to be released in March).
It will be a great improvement for us if Saxon HE 10 was integrated in the next version of Oxygen.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Mar 11, 2022 3:43 pm
by tavy
Hello Isabelle,
We just released Oxygen version 24.1.
The new version includes Saxon 10.6 as built-in transformer, as well as Saxon 10.7 and Saxon 11.2 as add-ons.
For the complete list of features, you can go to:
https://www.oxygenxml.com/xml_editor/wh ... SLT_XQuery
Best Regards,
Octavian
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Fri Mar 11, 2022 3:45 pm
by Isabelle
Hi,
Thanks for the feedback.
We will check that soon.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Wed Jan 03, 2024 8:38 pm
by Isabelle
Hello,
For information with oxygen 25.0, the xsl:evaluate method works fine.
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Posted: Thu Jan 04, 2024 8:43 am
by Radu
Hi Isabelle,
Thanks for updating the post!
Regards,
Radu