Custom IDElementLocator

Post here questions and problems related to oXygen frameworks/document types.
sebastienlavandier
Posts: 124
Joined: Tue May 29, 2012 5:42 pm

Custom IDElementLocator

Post by sebastienlavandier » Wed Oct 30, 2013 7:53 pm

Hi,

I implemented in my css this :

Code: Select all

GRPHCREF:before {
link:attr(REFID);
color: #1e91ca;
content: "Graphic Ref : " attr(REFID);
}
and I want to link this to an element ID name "KEY". To do that,I have add in my file.framewok :

Code: Select all

<field name="elementLocatorExtension">				<String>com.author.framework.CustomElementLocatorProvider</String>
</field>
Also, I implemented this :

Code: Select all

public class CustomElementLocatorProvider extends DefaultElementLocatorProvider {

@Override
public ElementLocator getElementLocator(IDTypeVerifier idVerifier, String link) {

// Locate link element by ID
return new CustomIDElementLocator(idVerifier, link);
}
}
And of course, this :

Code: Select all

public class CustomIDElementLocator extends IDElementLocator {

public CustomIDElementLocator(IDTypeVerifier idTypeVerifier, String s) {
super(idTypeVerifier, s);
}

/**
* @see ro.sync.ecss.extensions.api.link.ElementLocator#startElement(java.lang.String, java.lang.String, java.lang.String, ro.sync.ecss.extensions.api.link.Attr[])
*/
@Override
public boolean startElement(String uri, String localName, String name, Attr[] atts) {
boolean elementFound = false;
for (int i = 0; i < atts.length; i++) {
if (link.equals(atts[i].getValue())) {
if("KEY".equals(atts[i].getQName())) {
// xml:id attribute
elementFound = true;
} else {
// Check if attribute has ID type
String attrLocalName =
ExtensionUtil.getLocalName(atts[i].getQName());
String attrUri = atts[i].getNamespace();
if (idVerifier.hasIDType(localName, uri, attrLocalName, attrUri)) {
elementFound = true;
}
}
}
}

return elementFound;
}
}
But unfortunately,these classes are never called... and I don't understand why

Do you have an idea ?

Thanks in advance for your help.
Sébastien

Radu
Posts: 6180
Joined: Fri Jul 09, 2004 5:18 pm

Re: Custom IDElementLocator

Post by Radu » Thu Oct 31, 2013 12:56 pm

Hi Sébastien,

If the "REFID" attribute is defined as IDREF and if the "KEY" attribute is defined as an "ID" in the associated DTDs then linking between them should work just by setting the property which you have already set in the CSS:

Code: Select all

link:attr(REFID);
because the ro.sync.ecss.extensions.commons.DefaultElementLocatorProvider default locator provider is used for any framework which does not specify a custom locator provider.

Once you modify the document type and set in the "Document Type Edit" dialog a different extension for the Link target element finder then your extension should be used instead.
Did you manually open and modify the framework configuration file or did you use Oxygen's "Document Type Edit" dialog to accomplish this?

I do not quite know why this works for you.

Another alternative is to overwrite the method ro.sync.ecss.extensions.api.ExtensionsBundle.createElementLocatorProvider() in your custom extensions bundle implementation but setting the extension separate in the document type should take precedence over the element locator provider created in the extensions bundle.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

sebastienlavandier
Posts: 124
Joined: Tue May 29, 2012 5:42 pm

Re: Custom IDElementLocator

Post by sebastienlavandier » Thu Oct 31, 2013 1:57 pm

Hi Radu,

Indeed, the "REFID" attribute wasn't declared like an IDREF, and the "KEY" atribute wasn't declared like an ID too.

So, I modified my file.framework for do not use the "CustomElementLocatorProvider" :

Code: Select all

<field name="elementLocatorExtension"><null/></field>
But unfortunetly, the link between these IDs doesn't work. I have an error message that indicate :
"Can't open the file:
ro.sync.ecss.extensions.api.component.AuthorComponentException: java.io.FileNotFoundException:"

Do you have an other great idea ?

Thanks in advance for your help
Sébastien

Radu
Posts: 6180
Joined: Fri Jul 09, 2004 5:18 pm

Re: Custom IDElementLocator

Post by Radu » Thu Oct 31, 2013 5:39 pm

Hi Sébastien,

You are working in the AuthorComponent code, right? Could you post the entire stack trace of that thrown exception?

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

Radu
Posts: 6180
Joined: Fri Jul 09, 2004 5:18 pm

Re: Custom IDElementLocator

Post by Radu » Thu Oct 31, 2013 5:42 pm

Hi,

Please also try this modification in the CSS:

link: "#" attr(REFID);

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

sebastienlavandier
Posts: 124
Joined: Tue May 29, 2012 5:42 pm

Re: Custom IDElementLocator

Post by sebastienlavandier » Thu Oct 31, 2013 6:43 pm

Hi Radu,
Sorry, but same problem again.
It's trying to open the link file ...

Do you have an other idea ?

Thanks in advance for your help
Sébastien

Radu
Posts: 6180
Joined: Fri Jul 09, 2004 5:18 pm

Re: Custom IDElementLocator

Post by Radu » Fri Nov 01, 2013 11:41 am

Hi Sébastien,

Did you define those KEY and REFID attributes as xs:ID and xs:IDREF in the associated schema?

Here's exactly what I tested on my side:

I have a small sample XML like:

Code: Select all

<?xml-stylesheet type="text/css" href="test.css"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="test.xsd">
<div KEY="a">
Some text
</div>
<divref REFID="a"/>
</root>
with a test.css like:

Code: Select all

*{
display:block;
}

divref:before {
link:"#" attr(REFID);
color: #1e91ca;
content: "Graphic Ref : " attr(REFID);
}
and a "test.xsd" XML Schema like:

Code: Select all

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="div"/>
<xs:element ref="divref"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="div">
<xs:complexType mixed="true">
<xs:attributeGroup ref="attlist.div"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="attlist.div">
<xs:attribute name="KEY" type="xs:ID"/>
</xs:attributeGroup>
<xs:element name="divref">
<xs:complexType>
<xs:attributeGroup ref="attlist.divref"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="attlist.divref">
<xs:attribute name="REFID" type="xs:IDREF"/>
</xs:attributeGroup>
</xs:schema>
As you can see the schema defines the @KEY attribute as xs:ID and the @REFID attribute as IDREF.
Without any further framework extension, I switch the XML document to the Author mode, click the link and the target is properly located.

If you still cannot make this work please send us (support@oxygenxml.com) some sample files + framework configuration in order to reproduce the issue on our side.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

Post Reply