How to insert a custom ID in newly inserted elements automatically?
Having trouble deploying Oxygen XML Web Author? Got a bug to report? Post it all here.
-
- Posts: 43
- Joined: Thu Feb 16, 2023 11:00 pm
How to insert a custom ID in newly inserted elements automatically?
Hi!
Is there a way to insert an element XML with the ID attribute already filled?
We are going to create a custom rule for ID creation, and we need each inserted element to be created with this custom ID.
Is there a way to invoke this method when inserting each XML element?
Or an action that is triggered during the element inclusion, via content completion?
We don't have a list of elements containing IDs. However, I know that the Oxygen can read the schema and check if the element should have an ID. If it should, we want to invoke the custom ID generation function.
I notice that there's a method that can be invoked through an action. However, we need the element to already have the ID when it's created, rather than requiring the user to click a button to trigger the ID generation action.
Could you please assist?
Is there a way to insert an element XML with the ID attribute already filled?
We are going to create a custom rule for ID creation, and we need each inserted element to be created with this custom ID.
Is there a way to invoke this method when inserting each XML element?
Or an action that is triggered during the element inclusion, via content completion?
We don't have a list of elements containing IDs. However, I know that the Oxygen can read the schema and check if the element should have an ID. If it should, we want to invoke the custom ID generation function.
I notice that there's a method that can be invoked through an action. However, we need the element to already have the ID when it's created, rather than requiring the user to click a button to trigger the ID generation action.
Could you please assist?
-
- Posts: 9434
- Joined: Fri Jul 09, 2004 5:18 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hi,
Is the attribute defined as required for the XML document in the DTD or Schema associated with it?
Are you working with the XML document in the Text editing mode or in the Author visual editing mode? Do you want the ID generation for the inserted XML element to work both when editing in the Text and the Author visual editing modes?
For the Author visual editing mode we have framework customizations which would allow you to replace in the content completion window that specific element with a custom Author action which would give you better control over what to insert:
https://blog.oxygenxml.com/topics/custo ... etion.html
Other than that, a framework based extension which would work both in the Text and Author modes and take control over the content completion elements would need to be implemented in Java:
https://www.oxygenxml.com/doc/versions/ ... ndler.html
Regards,
Radu
Is the attribute defined as required for the XML document in the DTD or Schema associated with it?
Are you working with the XML document in the Text editing mode or in the Author visual editing mode? Do you want the ID generation for the inserted XML element to work both when editing in the Text and the Author visual editing modes?
For the Author visual editing mode we have framework customizations which would allow you to replace in the content completion window that specific element with a custom Author action which would give you better control over what to insert:
https://blog.oxygenxml.com/topics/custo ... etion.html
Other than that, a framework based extension which would work both in the Text and Author modes and take control over the content completion elements would need to be implemented in Java:
https://www.oxygenxml.com/doc/versions/ ... ndler.html
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 43
- Joined: Thu Feb 16, 2023 11:00 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hi Radu!
Yes, the attribute is defined as required in the Schema associated.
We will work only with Author visual editing mode.
The idea is that Oxygen can intercept any element that is inserted via content completion and call a class that creates an ID for each situation.
Is there a way to make an action for all elements or do we have to map all elements in advance and create an action for each?
Yes, the attribute is defined as required in the Schema associated.
We will work only with Author visual editing mode.
The idea is that Oxygen can intercept any element that is inserted via content completion and call a class that creates an ID for each situation.
Is there a way to make an action for all elements or do we have to map all elements in advance and create an action for each?
-
- Posts: 9434
- Joined: Fri Jul 09, 2004 5:18 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hi,
Indeed by default Oxygen inserts the required attribute name but does not insert a value for it, expecting the end user to set the value themselves.
I assume you have already created a framework configuration for your XML vocabulary in the Oxygen Preferences->"Document Type Association" page.
If you edit your framework configuration, in the "Classpath" tab you can add a reference to a "resources" folder from inside your framework folder:
and then create a "resources" folder inside your framework folder. Then inside the "resources" folder create a file named "cc_config.xml" with the content:
More about what the cc_config.xml can do:
https://www.oxygenxml.com/doc/versions/ ... ually.html
Basically the value uses an Oxygen editor variable named ${id} which will get expanded when the element is inserted.
There are other Oxygen editor variables which may be useful like ${uuid} if you want an even stronger (but much longer) id value.
There is yet another another way to take full control over the generated ID attributes if you are or know a Java developer who is willing to work on this.
If you edit your framework customization in the Oxygen Preferences->"Document Type Association" page, in the Classpath tab you can add a reference to a custom Java JAR library. Then in the "Extensions" tab there is an extension named "Unique attributes recognizer":
https://www.oxygenxml.com/doc/versions/ ... nizer.html
Regards,
Radu
Indeed by default Oxygen inserts the required attribute name but does not insert a value for it, expecting the end user to set the value themselves.
I assume you have already created a framework configuration for your XML vocabulary in the Oxygen Preferences->"Document Type Association" page.
If you edit your framework configuration, in the "Classpath" tab you can add a reference to a "resources" folder from inside your framework folder:
Code: Select all
${framework}/resources/
Code: Select all
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oxygenxml.com/ns/ccfilter/config http://www.oxygenxml.com/ns/ccfilter/config/ccConfigSchemaFilter.xsd"
xmlns="http://www.oxygenxml.com/ns/ccfilter/config">
<elementProposals path="yourElementName">
<insertAttribute name="id" value="prefix_${id}"/>
</elementProposals>
</config>
https://www.oxygenxml.com/doc/versions/ ... ually.html
Basically the value uses an Oxygen editor variable named ${id} which will get expanded when the element is inserted.
There are other Oxygen editor variables which may be useful like ${uuid} if you want an even stronger (but much longer) id value.
There is yet another another way to take full control over the generated ID attributes if you are or know a Java developer who is willing to work on this.
If you edit your framework customization in the Oxygen Preferences->"Document Type Association" page, in the Classpath tab you can add a reference to a custom Java JAR library. Then in the "Extensions" tab there is an extension named "Unique attributes recognizer":
https://www.oxygenxml.com/doc/versions/ ... nizer.html
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 43
- Joined: Thu Feb 16, 2023 11:00 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hello Radu!
Thank you so much for your answer.
We decided to use a Java operation with an extension for ExtensionsBundle.
We created the idGenerationDefaultOptions.xml file which worked great for XML without NAMESPACE declared.
But for the 2300 specification we have xmlns="http://www.ataebiz.org/XMLSchema".
In the cc_config.xml file we use <elementProposals xmlns:ata="http://www.ataebiz.org/XMLSchema" path="ata:para">.
We have to declare the NAMESPACE in the idGenerationDefaultOptions.xml file or do we have to resolve the namespace via Java in the ExtensionsBundle extended class?
How do we proceed?
Thank you!
Thank you so much for your answer.
We decided to use a Java operation with an extension for ExtensionsBundle.
We created the idGenerationDefaultOptions.xml file which worked great for XML without NAMESPACE declared.
But for the 2300 specification we have xmlns="http://www.ataebiz.org/XMLSchema".
In the cc_config.xml file we use <elementProposals xmlns:ata="http://www.ataebiz.org/XMLSchema" path="ata:para">.
We have to declare the NAMESPACE in the idGenerationDefaultOptions.xml file or do we have to resolve the namespace via Java in the ExtensionsBundle extended class?
How do we proceed?
Thank you!
-
- Posts: 9434
- Joined: Fri Jul 09, 2004 5:18 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hi,
Did you created your own Java class which extends our base "ro.sync.ecss.extensions.commons.id.DefaultUniqueAttributesRecognizer" class?
And return this custom class on the "ro.sync.ecss.extensions.api.ExtensionsBundle.getUniqueAttributesIdentifier()" callback?
Looking at our source code in the "ro.sync.ecss.extensions.commons.id.DefaultUniqueAttributesRecognizer.getGenerateIDAttributeQName(AuthorElement, String[], boolean)" method it seems we interpret these elements specified in the "idGenerationDefaultOptions.xml" as being local names:
So we are not namespace aware in this regard, for your case you would need to specify the element local name there, without any prefix like:
Regards,
Radu
Did you created your own Java class which extends our base "ro.sync.ecss.extensions.commons.id.DefaultUniqueAttributesRecognizer" class?
And return this custom class on the "ro.sync.ecss.extensions.api.ExtensionsBundle.getUniqueAttributesIdentifier()" callback?
Looking at our source code in the "ro.sync.ecss.extensions.commons.id.DefaultUniqueAttributesRecognizer.getGenerateIDAttributeQName(AuthorElement, String[], boolean)" method it seems we interpret these elements specified in the "idGenerationDefaultOptions.xml" as being local names:
Code: Select all
<generateForElement>...</generateForElement>
Code: Select all
<generateForElement>para</generateForElement>
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 43
- Joined: Thu Feb 16, 2023 11:00 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hi Radu!
I found the problem.
We override getGenerateIDAttributeQName to check whether or not the element parameter can receive an ID depending on the Schema.
We use:
WhatAttributesCanGoHereContext attrContext = authorSchemaManager.createWhatAttributesCanGoHereContext(element);
oxyAttrList = authorSchemaManager.whatAttributesCanGoHere(attrContext);
However, the system is not returning the list of attributes of the sent element.
Using authorSchemaManager.getElementDescription(attrContext).getAttributes().toString() the system returns the attributes of the parent element and not the requested element.
Are we collecting the list of attributes wrongly or is there a problem with the schema?
Regards,
Audye
I found the problem.
We override getGenerateIDAttributeQName to check whether or not the element parameter can receive an ID depending on the Schema.
We use:
WhatAttributesCanGoHereContext attrContext = authorSchemaManager.createWhatAttributesCanGoHereContext(element);
oxyAttrList = authorSchemaManager.whatAttributesCanGoHere(attrContext);
However, the system is not returning the list of attributes of the sent element.
Using authorSchemaManager.getElementDescription(attrContext).getAttributes().toString() the system returns the attributes of the parent element and not the requested element.
Are we collecting the list of attributes wrongly or is there a problem with the schema?
Regards,
Audye
-
- Posts: 9434
- Joined: Fri Jul 09, 2004 5:18 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hello Audye,
Please see some remarks below:
It means to say that it returns the list of possible attributes, except for the attributes which are already present on the element.
For example for an element like this:
it already has the @id and @type attributes present on it so the authorSchemaManager.whatAttributesCanGoHere will return all other attributes which can be inserted, but it will not return "id" and "type" because they are already set on the element.
You can also use code like this if you want to obtain all possible attributes which can be added to the element:
One thing to keep in mind, calls to the authorSchemaManager do not take that much time to compute but the getGenerateIDAttributeQName may be called quite often. For example if you copy a large piece of DITA content from one topic and paste it in another the "getGenerateIDAttributeQName" will get called for all DITA XML elements in the copied content, so you may experience a slowdown if you use very frequent calls to the authorSchemaManager, maybe you could have also some kind of intermediary cache of element name mapped to possible attributes.
Regards,
Radu
Please see some remarks below:
I understand.We override getGenerateIDAttributeQName to check whether or not the element parameter can receive an ID depending on the Schema.
This should work, the Javadoc for the authorSchemaManager.whatAttributesCanGoHere states:We use:
WhatAttributesCanGoHereContext attrContext = authorSchemaManager.createWhatAttributesCanGoHereContext(element);
oxyAttrList = authorSchemaManager.whatAttributesCanGoHere(attrContext);
However, the system is not returning the list of attributes of the sent element.
Code: Select all
Examines the grammar and decides what attributes can be inserted in the parent element, after the list of attributes names.
For example for an element like this:
Code: Select all
<hazardstatement id="hazardstatement_t1y_1kk_syb" type="important">
The WhatAttributesCanGoHereContext is specifically built to be used with the whatAttributesCanGoHere method.Using authorSchemaManager.getElementDescription(attrContext).getAttributes().toString() the system returns the attributes of the parent element and not the requested element.
You can also use code like this if you want to obtain all possible attributes which can be added to the element:
Code: Select all
WhatElementsCanGoHereContext ctxt =
authorSchemaManager.createWhatElementsCanGoHereContext(element.getStartOffset() + 1);
CIElement elementDescription = authorSchemaManager.getElementDescription(ctxt);
List allAttributes = elementDescription.getAttributes();
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 43
- Joined: Thu Feb 16, 2023 11:00 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Thank you very much Radu!
It solved the whole problem.
We will take into account what you mentioned about the performance of copying and pasting content.
I have one last doubt at the moment.
Is there any way to call the ExtensionBundle ID creation method when opening the document for editing?
When opening the XML document for editing, we would like Oxygen to scan all the elements that are in the XML in order to generate the missing IDs.
Is there any way to place a listener via WEB or JAVA in our framework to carry out this ID generation activity?
Code: Select all
WhatElementsCanGoHereContext ctxt = author SchemaManager.create WhatElementsCanGoHereContext(element.getStartOffset() + 1);
We will take into account what you mentioned about the performance of copying and pasting content.
I have one last doubt at the moment.
Is there any way to call the ExtensionBundle ID creation method when opening the document for editing?
When opening the XML document for editing, we would like Oxygen to scan all the elements that are in the XML in order to generate the missing IDs.
Is there any way to place a listener via WEB or JAVA in our framework to carry out this ID generation activity?
-
- Posts: 9434
- Joined: Fri Jul 09, 2004 5:18 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hi,
Maybe something like this might work, but it would need to be tested:
Also the document will appear as modified to the user if you make changes to it after it is loaded.
Regards,
Radu
Maybe something like this might work, but it would need to be tested:
Code: Select all
public class MyExtensionsBundle extends ExtensionsBundle {
/**
* @see ro.sync.ecss.extensions.api.ExtensionsBundle#createAuthorExtensionStateListener()
*/
@Override
public AuthorExtensionStateListener createAuthorExtensionStateListener() {
return new AuthorExtensionStateListener() {
@Override
public String getDescription() {
return null;
}
@Override
public void deactivated(AuthorAccess authorAccess) {
}
@Override
public void activated(AuthorAccess authorAccess) {
//This is called when an XML is opened in the Author visual editing mode
//or when the XML is switched from the Text mode to the Author visual editing mode
getUniqueAttributesIdentifier().assignUniqueIDs(0, authorAccess.getDocumentController().getAuthorDocumentNode().getLength(), false);
}
};
}
/**
* @see ro.sync.ecss.extensions.api.ExtensionsBundle#getUniqueAttributesIdentifier()
*/
@Override
public UniqueAttributesRecognizer getUniqueAttributesIdentifier() {
return new MyUniqueAttrsIdentifier();
}
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 43
- Joined: Thu Feb 16, 2023 11:00 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hello Radu!
Your suggestion worked perfectly!
It is already tested and confirmed.
The only change I have to make is to call uniqueAttributesRecognizer.activated(authorAccess) first, so it loaded the methods that I changed due to our customizations.
I saw that using the cc_config.xml file we were able to create generation patterns for more than one attribute.
By extensibleBundle we have only 1 option in the idGenerationDefaultOptions.xml file which is the <idAttribute>id</idAttribute> entry.
Is there a way to use extensibleBundle to automatically generate the ID and another attribute on the same element?
Your suggestion worked perfectly!
It is already tested and confirmed.
The only change I have to make is to call uniqueAttributesRecognizer.activated(authorAccess) first, so it loaded the methods that I changed due to our customizations.
Code: Select all
return new AuthorExtensionStateListener() {
@Override
public String getDescription() {
return uniqueAttributesRecognizer.getDescription();
}
/**
* @see ro.sync.ecss.extensions.api.AuthorExtensionStateListener#deactivated(ro.sync.ecss.extensions.api.AuthorAccess)
*/
@Override
public void deactivated(AuthorAccess authorAccess) {
uniqueAttributesRecognizer.deactivated(authorAccess);
}
/**
* @see ro.sync.ecss.extensions.api.AuthorExtensionStateListener#activated(ro.sync.ecss.extensions.api.AuthorAccess)
*/
@Override
public void activated(AuthorAccess authorAccess) {
//have to call activated before
uniqueAttributesRecognizer.activated(authorAccess);
uniqueAttributesRecognizer.assignUniqueIDs(0, authorAccess.getDocumentController().getAuthorDocumentNode().getLength(), false);
}
}
Code: Select all
<elementProposals path="para">
<insertAttribute name="id" value="${xpath_eval(/*/@id)}_${uuid}"/>
<insertAttribute name="idCustom" value="CUSTOM_${uuid}"/>
</elementProposals>
By extensibleBundle we have only 1 option in the idGenerationDefaultOptions.xml file which is the <idAttribute>id</idAttribute> entry.
Is there a way to use extensibleBundle to automatically generate the ID and another attribute on the same element?
-
- Posts: 9434
- Joined: Fri Jul 09, 2004 5:18 pm
Re: How to insert a custom ID in newly inserted elements automatically?
Hi,
Please see some more remarks below:
ro.sync.exml.workspace.api.util.UtilAccess.addCustomEditorVariablesResolver(EditorVariablesResolver)
https://www.oxygenxml.com/InstData/Edit ... sResolver-
The complete Java source code for the "ro.sync.ecss.extensions.commons.id.DefaultUniqueAttributesRecognizer" should be in our Maven SDK:
https://www.oxygenxml.com/oxygen_sdk.html
Regards,
Radu
Please see some more remarks below:
RightThe only change I have to make is to call uniqueAttributesRecognizer.activated(authorAccess) first, so it loaded the methods that I changed due to our customizations.
Yes, and also you can use your own custom editor variables like ${customID} for which you can add a custom editor variables resolver:I saw that using the cc_config.xml file we were able to create generation patterns for more than one attribute.
ro.sync.exml.workspace.api.util.UtilAccess.addCustomEditorVariablesResolver(EditorVariablesResolver)
https://www.oxygenxml.com/InstData/Edit ... sResolver-
Instead of extending the DefaultUniqueAttributesRecognizer which is based on that XML configuration file which is more rigid than what you want you could implement directly the "ro.sync.ecss.extensions.api.UniqueAttributesRecognizer" interface and implement the "assignUniqueIDs" method from the ground up.By extensibleBundle we have only 1 option in the idGenerationDefaultOptions.xml file which is the <idAttribute>id</idAttribute> entry.
Is there a way to use extensibleBundle to automatically generate the ID and another attribute on the same element?
The complete Java source code for the "ro.sync.ecss.extensions.commons.id.DefaultUniqueAttributesRecognizer" should be in our Maven SDK:
https://www.oxygenxml.com/oxygen_sdk.html
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
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