Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
In the Author Component, I try to test
from https://www.oxygenxml.com/doc/versions/ ... -proposalsConfiguring Proposed Values in the Context that the Content Completion was Invoked
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
-
- Posts: 1012
- Joined: Wed Nov 16, 2005 11:11 am
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Post by alex_jitianu »
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, ./*))"/>
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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();
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]
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
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)
Regards,
Radu
<oXygen/> XML Editor
http://www.oxygenxml.com
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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
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
<oXygen/> XML Editor
http://www.oxygenxml.com
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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;
}
}
I do not understand what I miss, any idea ?[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
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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();
}
}
}
Radu
<oXygen/> XML Editor
http://www.oxygenxml.com
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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
Thanks to you, we can compile XSL with Saxon PE in java but we still have issue.
We try to implement
that we find here https://www.oxygenxml.com/doc/versions/ ... -proposals.Configuring Proposed Values in the Context that the Content Completion was Invoked
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)
Code: Select all
<match elementName="property" attributeName="value">
<xslt href="get_values.xsl" useCache="false" action="replace"/>
</match>
Regards,
Isabelle
-
- Posts: 1012
- Joined: Wed Nov 16, 2005 11:11 am
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Post by alex_jitianu »
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>
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);
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
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
-
- Posts: 1012
- Joined: Wed Nov 16, 2005 11:11 am
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Post by alex_jitianu »
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);
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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));
Did I miss something ?
Regards,
Isabelle
-
- Posts: 1012
- Joined: Wed Nov 16, 2005 11:11 am
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Post by alex_jitianu »
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
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
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>
Thanks,
Regards,
Isabelle
-
- Posts: 1012
- Joined: Wed Nov 16, 2005 11:11 am
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Post by alex_jitianu »
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);
}
};
}
Best regards,
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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).
Unfortunately there is no workaround for this other than using the Java API instead and implementing a SchemaManagerFilter.Code: Select all
<xsl:variable name="propertyElement" select="saxon:eval(saxon:expression($contextElementXPathExpression, ./*))"/>
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
-
- Posts: 1012
- Joined: Wed Nov 16, 2005 11:11 am
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Post by alex_jitianu »
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>
Alex
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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>
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:?]
Thanks,
Regards,
Isabelle
-
- Posts: 1012
- Joined: Wed Nov 16, 2005 11:11 am
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
Post by alex_jitianu »
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
Thanks for the feedback.
It will be a great improvement for us if Saxon HE 10 was integrated in the next version of Oxygen.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).
Regards,
Isabelle
Re: Configuring Proposed Values in the Context that the Content Completion was Invoked - SAXON
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
<oXygen/> XML Editor
http://www.oxygenxml.com
Return to “SDK-API, Frameworks - Document Types”
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service