Referencing list from another XML file
Post here questions and problems related to oXygen frameworks/document types.
-
- Posts: 26
- Joined: Wed Apr 10, 2013 12:34 pm
- Location: Utrecht, Netherlands
Referencing list from another XML file
Hi all,
I'm trying to do something that I think should be fairly simple, but so far it hasn't been... I'd like to generate the items for a combobox using the values from another set of XML documents using my own private URI scheme. For example, for any field in the main XML that needs to have a person selected for it, I'd like to create a combobox with values from the person.xml file. Of course, this requires an XQuery or XSLT call to produce the results (I'm using XQuery because I'm more familiar with it and I find it to be easier to use). This could be (perhaps) the most basic use case for editing documents in Oxygen, but so far I don't see any easy or obvious way to do it. In the relational database world, this is THE use case for data - select a person from the Person table, the values being generated by a SQL statement. The CSS provided by Oxygen assumes all values are located in the document itself - but come on, how often is that really the case?
I've tried using a ReferenceResolver, but that assumes that I want to insert data from another file into the main one and it doesn't allow a user to select the record to be linked. I've looked at the LinkTextResolver, but again that just generates some text to be displayed by a link. I've recently decided to add a CSS combobox at runtime using a Styles Filter, but that class does not have access to AuthorAccess, so I can't get access to the EditorVariables (to resolve where the files are that my private URI scheme refers to) and the XMLUtilAccess class which has transformation functions.
Argh! This should be the easiest, simplest thing to do, and yet I can't see anywhere in the documentation where this use case is explicitly described except for the example using a custom Styles Filter. Any help would be greatly appreciated! If nothing else, can anyone tell me how to pass a reference to AuthorAccess to my custom Styles Filter from an Extensions bundle or even better, how I can access it from anywhere in my application? Is there a global value passed into the ExtensionsBundle at any point? So far I'm not seeing one...
Thanks in advance for any help you can provide!
I'm trying to do something that I think should be fairly simple, but so far it hasn't been... I'd like to generate the items for a combobox using the values from another set of XML documents using my own private URI scheme. For example, for any field in the main XML that needs to have a person selected for it, I'd like to create a combobox with values from the person.xml file. Of course, this requires an XQuery or XSLT call to produce the results (I'm using XQuery because I'm more familiar with it and I find it to be easier to use). This could be (perhaps) the most basic use case for editing documents in Oxygen, but so far I don't see any easy or obvious way to do it. In the relational database world, this is THE use case for data - select a person from the Person table, the values being generated by a SQL statement. The CSS provided by Oxygen assumes all values are located in the document itself - but come on, how often is that really the case?
I've tried using a ReferenceResolver, but that assumes that I want to insert data from another file into the main one and it doesn't allow a user to select the record to be linked. I've looked at the LinkTextResolver, but again that just generates some text to be displayed by a link. I've recently decided to add a CSS combobox at runtime using a Styles Filter, but that class does not have access to AuthorAccess, so I can't get access to the EditorVariables (to resolve where the files are that my private URI scheme refers to) and the XMLUtilAccess class which has transformation functions.
Argh! This should be the easiest, simplest thing to do, and yet I can't see anywhere in the documentation where this use case is explicitly described except for the example using a custom Styles Filter. Any help would be greatly appreciated! If nothing else, can anyone tell me how to pass a reference to AuthorAccess to my custom Styles Filter from an Extensions bundle or even better, how I can access it from anywhere in my application? Is there a global value passed into the ExtensionsBundle at any point? So far I'm not seeing one...
Thanks in advance for any help you can provide!
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Referencing list from another XML file
Post by alex_jitianu »
Hello,
This is indeed a common use case for Oxygen and we have several ways to achieve your goal.
One of them is exactly the one you tried, namely by adding an combo box form control by using a StylesFilter. You are right, the documentation is a bit unclear about how to obtain the AuthorAccess instance. One way to do it is presented in the code snippet below:
We already have recorded an issue to pass an AuthorAccess instance to the StylesFilter, so it will be available in one of the next versions.
Another approach which does not imply using Java is using the oxy_xpath() function (with XPath 2.0 features) to specify the values to be displayed in the oxy_combobox. For example, if you want to propose person names based on the data in another XML file (db.xml in our example) your CSS will look as below:
There is a third approach which has the advantage of offering these values in the content completion window and in the Attributes View besides the combobox form control. It uses the SchemaManagerFilter API interface which allows you to contribute values to the schema proposed content completion items. An example of using this API can be found in the user manual: http://oxygenxml.com/doc/ug-editor/#top ... ndler.html.
We have worked on a SchemaManagerFilter implementation that was able to read a configuration XML file (not yet released but fully functional). In this configuration file you could say that the values for an attribute or element should be obtained by executing an XSLT or XQuery. So all you have to do is write a configuration XML file and an XQuery script. If you are interested in it please let me know and I can send it to you to give it a try.
If you have further questions, please let me know.
This is indeed a common use case for Oxygen and we have several ways to achieve your goal.
One of them is exactly the one you tried, namely by adding an combo box form control by using a StylesFilter. You are right, the documentation is a bit unclear about how to obtain the AuthorAccess instance. One way to do it is presented in the code snippet below:
Code: Select all
WSEditor editorAccess =
PluginWorkspaceProvider.getPluginWorkspace().getCurrentEditorAccess(PluginWorkspace.MAIN_EDITING_AREA);
if (editorAccess != null) {
WSEditorPage currentPage = editorAccess.getCurrentPage();
if (currentPage instanceof WSAuthorEditorPage) {
AuthorAccess authorAccess = ((WSAuthorEditorPage) currentPage).getAuthorAccess();
}
}
Another approach which does not imply using Java is using the oxy_xpath() function (with XPath 2.0 features) to specify the values to be displayed in the oxy_combobox. For example, if you want to propose person names based on the data in another XML file (db.xml in our example) your CSS will look as below:
Code: Select all
combo {
content: "persons"
oxy_combobox(edit, '#text', values, oxy_xpath('string-join(doc("./db.xml")//person/@name, ",")'));
}
We have worked on a SchemaManagerFilter implementation that was able to read a configuration XML file (not yet released but fully functional). In this configuration file you could say that the values for an attribute or element should be obtained by executing an XSLT or XQuery. So all you have to do is write a configuration XML file and an XQuery script. If you are interested in it please let me know and I can send it to you to give it a try.
If you have further questions, please let me know.
-
- Posts: 26
- Joined: Wed Apr 10, 2013 12:34 pm
- Location: Utrecht, Netherlands
Re: Referencing list from another XML file
Thank you for your detailed reply! That does help immensely! The code snippet to get the AuthorAccess reference is very handy. I also didn't know there was another way of doing this using the SchemaManager - that sounds like a very nice option, since the values are embedded at a level "closer" to the data, so to speak. And I can still use the combobox via CSS to render those fields (with the list of values) since it's embedded in the Schema, so to speak, right? I would definitely like to give that a try. Can you send me the code/files for it and any documentation you have?
Thanks for your help!
Thanks for your help!
Cheers,
M
M
-
- Posts: 26
- Joined: Wed Apr 10, 2013 12:34 pm
- Location: Utrecht, Netherlands
Re: Referencing list from another XML file
OK, I've been playing around with the StylesFilter approach again, but I'm finding that the code snippet you gave me doesn't actually give me access to AuthorAccess when the styles load initially. When transitioning from Text to Author mode, the call to getCurrentPage() doesn't return the Author page, so I can't get AuthorAccess that way (reliably at least - it works when I debug the code and step through it!).
The main thing I need AuthorAccess for is to expandEditorVariables within the current framework and within the current project. So I tried the code below using the PluginWorkspace and WSEditor. This expands the project variable correctly for one path, but not the frameworks variable - perhaps because the editor isn't associated with a framework yet, since it's transitioning to Author mode? Keep in mind that this code is being called by my implementation of the StylesFilter Interface, so it fires as the Author view is loading.
Can you tell me how to do this? Or can I get access to these variables another way?
Here's the code I'm using:
Thanks in advance for any help you can provide!
The main thing I need AuthorAccess for is to expandEditorVariables within the current framework and within the current project. So I tried the code below using the PluginWorkspace and WSEditor. This expands the project variable correctly for one path, but not the frameworks variable - perhaps because the editor isn't associated with a framework yet, since it's transitioning to Author mode? Keep in mind that this code is being called by my implementation of the StylesFilter Interface, so it fires as the Author view is loading.
Can you tell me how to do this? Or can I get access to these variables another way?
Here's the code I'm using:
Code: Select all
String sourceBase = EditorVariables.PROJECT_DIRECTORY + "/contextual_info/person.xml";
String xqueryBase = EditorVariables.FRAMEWORK_DIRECTORY + "/resources/contextual_info.xql";
PluginWorkspace ws = PluginWorkspaceProvider.getPluginWorkspace();
WSEditor access = ws.getCurrentEditorAccess(PluginWorkspace.MAIN_EDITING_AREA);
String sourceExpanded = ws.getUtilAccess().expandEditorVariables(
sourceBase, access.getEditorLocation()
);
String xqueryExpanded = ws.getUtilAccess().expandEditorVariables(
xqueryBase, access.getEditorLocation()
);
System.out.println(sourceExpanded);
// returns /home/user/Documents/Projects/emst/contextual_info/person.xml
System.out.println(xqueryExpanded);
// returns ${frameworkDir}/resources/contextual_info.xql
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Referencing list from another XML file
Post by alex_jitianu »
Hi,
If you use PluginWorkspaceProvider.getPluginWorkspace().getUtilAccess() to get the UtilAccess the framework related editor variables are indeed not expanded. It's not an inherent limitation but just something we missed. Even more disturbing, the documentation states that these variables should be expanded no matter how you obtain the UtilAccess. I will add an issue to for the resolving to handle framework related variables no matter how the UtilAccess is obtained.
Until we fix the API I suggest to just ignore the StylesFilter.filter calls if the current page is not the AuthorPage. These calls come while the author document model is created and at this step we are only interested in the white-space properties. Afterwards, you will receives calls from the initial rendering and at that point the current page will be the AuthorPage.
Best regards,
Alex
If you use PluginWorkspaceProvider.getPluginWorkspace().getUtilAccess() to get the UtilAccess the framework related editor variables are indeed not expanded. It's not an inherent limitation but just something we missed. Even more disturbing, the documentation states that these variables should be expanded no matter how you obtain the UtilAccess. I will add an issue to for the resolving to handle framework related variables no matter how the UtilAccess is obtained.
Until we fix the API I suggest to just ignore the StylesFilter.filter calls if the current page is not the AuthorPage. These calls come while the author document model is created and at this step we are only interested in the white-space properties. Afterwards, you will receives calls from the initial rendering and at that point the current page will be the AuthorPage.
Best regards,
Alex
-
- Posts: 26
- Joined: Wed Apr 10, 2013 12:34 pm
- Location: Utrecht, Netherlands
Re: Referencing list from another XML file
Well, I'm glad I could help you guys out a bit
I've taken your advice and only fire my code when AuthorAccess is available and it is working now.
Thanks so much for your help!

Thanks so much for your help!
-
- Posts: 40
- Joined: Wed Jan 29, 2014 4:30 pm
Re: Referencing list from another XML file
Additional question on the same subject: Is it possible to constraint the list of returned values from the external file to the content of the current document ? Preferably in CSS syntax...
My case:
I am reading values in an external XML file using oxy_xpath to populate a popup in the CSS file.
The following code is OK:
However, I also need to filter values based on the content of the current document. Continuing my example, now that the user has selected a family, he should also select a product name and the popup should only contain the products related to the selected family.
In XSLT, I would use something like
but I could not find a way to do it in CSS/oxy_xpath syntax.
I can obtain the list of names as a string when I use
Alas, when I try to apply the string-join() function to that expression, it does not work. I suspect that quotes should be escaped (how?)...
Can you help ?
My case:
I am reading values in an external XML file using oxy_xpath to populate a popup in the CSS file.
The following code is OK:
Code: Select all
family {
visibility: -oxy-collapse-text;
content: oxy_editor(
type, popupSelection,
edit, "#text",
values, oxy_xpath('string-join(doc("http://shared/config.xml")//family/name, ",")'),
selectionMode, "single",
columns, 40
);
}
In XSLT, I would use something like
Code: Select all
<xsl:variable name="thisFamily" select="../family" />
<xsl:value-of select="string-join(doc('http://shared/config.xml')//family[name=$thisFamily]/product, ',')" />
I can obtain the list of names as a string when I use
Code: Select all
oxy_xpath(oxy_replace("doc('http://shared/config.xml')//family[name='$thisFamily']/product",'$thisFamily',oxy_xpath('../family/text()')))
Can you help ?
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Referencing list from another XML file
Post by alex_jitianu »
Hi,
Using oxy_xpath and oxy_replace together should work just fine for your use case. If you try something like this do you get an error message?
I will send you a logger configuration file on the email to get more insight about the situation.
Best regards,
Alex
Using oxy_xpath and oxy_replace together should work just fine for your use case. If you try something like this do you get an error message?
Code: Select all
oxy_xpath(oxy_replace("string-join(doc('http://shared/config.xml')//family[name='$thisFamily']/product, ',')",'$thisFamily',oxy_xpath('../family/text()')))
Best regards,
Alex
-
- Posts: 40
- Joined: Wed Jan 29, 2014 4:30 pm
Re: Referencing list from another XML file
Hi Alex,
your solution works perfectly, thanks!
My problem was that I did not use the oxy_replace function at the right place: I was trying and that does not work !
Your solution is working.
Thanks also for the logger configuration instructions you sent me; I do not think I will need them for this specific case but will save the info for future usage.
However, could you give me more explanation about the use of the double and single quotes in an expression?
I understand that you should use single quotes inside a string delimited by double quotes, but I was expecting to have the closing double quote later in the expression, that is just before the closing ) of the oxy_replace function; or to need quotes around the doc() expression...
Best regards,
Pascale
your solution works perfectly, thanks!
My problem was that I did not use the oxy_replace function at the right place: I was trying
Code: Select all
string-join(oxy_replace(...))
Your solution
Code: Select all
oxy_replace("string-join(...))
Thanks also for the logger configuration instructions you sent me; I do not think I will need them for this specific case but will save the info for future usage.
However, could you give me more explanation about the use of the double and single quotes in an expression?
I understand that you should use single quotes inside a string delimited by double quotes, but I was expecting to have the closing double quote later in the expression, that is just before the closing ) of the oxy_replace function; or to need quotes around the doc() expression...
Best regards,
Pascale
-
- Posts: 1016
- Joined: Wed Nov 16, 2005 11:11 am
Re: Referencing list from another XML file
Post by alex_jitianu »
Hi,
First thing to keep in mind is that oxy_xpath and oxy_replace are CSS functions while string-join is an XPath one. We use oxy_replace as a helper to build the final XPath expression that will be given to an oxy_xpath to execute. Combining these two functions (oxy_xpath and oxy_replace) can be quite confusing sometimes... Here is the same example with some indentation to make it easier to read:
Best regards,
Alex
First thing to keep in mind is that oxy_xpath and oxy_replace are CSS functions while string-join is an XPath one. We use oxy_replace as a helper to build the final XPath expression that will be given to an oxy_xpath to execute. Combining these two functions (oxy_xpath and oxy_replace) can be quite confusing sometimes... Here is the same example with some indentation to make it easier to read:
Code: Select all
oxy_xpath(
oxy_replace(
"string-join(doc('http://shared/config.xml')//family[name='$thisFamily']/product,',')",
"$thisFamily",
oxy_xpath("../family/text()")
)
)
Alex
Return to “SDK-API, Frameworks - Document Types”
Jump to
- 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