Hi,
Maybe I can tell you about something similar we implemented.
Let's say you open this sample file 
OXYGEN_INSTALL_DIR\samples\tei\TEI-P5.xml which is a TEI document (a custom XML vocabulary used to encode old manuscripts) in the Text editing mode. And you find in it this div:
If you place the caret inside the xml:id value you will get highlighted on the scroll bar all references to it.
So how does it work? This is not a plugin customization but a framework customization:
http://blog.oxygenxml.com/2014/08/the-o ... works.html
In the Oxygen Preferences->
Document Type Association page there is a document type association called 
TEI P5. It's activated when a TEI document is opened and it provides besides a default schema and CSS for visual editing also an extension JAR library in its "Classpath" tab.
In the "Extensions" tab there is a custom extensions bundle implementation set. The 
TEIP5ExtensionsBundle implementation is defined in that custom JAR library:
https://www.oxygenxml.com/doc/versions/ ... undle.html
and it overrides a method in the base:
Code: Select all
  
  /**
   * @see ro.sync.ecss.extensions.api.ExtensionsBundle#createIDTypeRecognizer()
   */
  @Override
  public IDTypeRecognizer createIDTypeRecognizer() {
    return new TEIP5IDTypeRecognizer();
  }
That 
TEIP5IDTypeRecognizer is responsible for recognizing IDs and ID references.
It's Java source looks like this:
Code: Select all
/**
 * Implementation of ID declarations and references recognizer for TEI P5 framework.
 * 
 * In this framework the IDs are declared in attributes with name 'id'. The references are recognized
 * in attributes ptr/@target or ref/@target, see http://www.tei-c.org/release/doc/tei-p5-doc/en/html/ref-ptr.html. 
 * 
 * @author radu_pisoi
 */
@API(type=APIType.INTERNAL, src=SourceType.PUBLIC)
public class TEIP5IDTypeRecognizer extends IDTypeRecognizer {
  
  /**
   * @see ro.sync.ecss.extensions.api.link.IDTypeRecognizer#detectIDType(java.lang.String, ro.sync.contentcompletion.xml.Context, java.lang.String, java.lang.String, java.lang.String, int)
   */
  @Override
  public List<IDTypeIdentifier> detectIDType(String systemID, Context context, String attrName,
      String attrNs, String attributeValue, int offset) throws CannotRecognizeIDException {
    List<IDTypeIdentifier> idTypeIdentifiers = new ArrayList<IDTypeIdentifier>();
    
    if(attributeValue != null && attributeValue.trim().length() > 0) {
      if("id".equals(attrName)) {
        // xml:id attribute
        DefaultIDTypeIdentifier idTypeIdentifier = new DefaultIDTypeIdentifier(attributeValue.trim(), true);
        idTypeIdentifiers.add(idTypeIdentifier);
      } else if("target".equals(attrName)) {
        // 'target' attribute
        Stack<ContextElement> elementStack = context.getElementStack();
        if(!elementStack.isEmpty()) {
          // For ptr/@target or ref/@target the ID references are recognized if the attribute value
          // has the pattern #id1 #id2
          String idValue = null;
          StringTokenizer stringTokenizer = new StringTokenizer(attributeValue, " ", true);
          int idx = 0;
          while(stringTokenizer.hasMoreTokens()) {
            String nextToken = stringTokenizer.nextToken();
            if(offset < idx) {
              break;
            }
            if(idx <= offset && offset <= idx + nextToken.length()) {
              // Current token include the offset
              if(!nextToken.equals(" ")) {
                idValue = nextToken;
              }
              break;
            }
            idx += nextToken.length();
          }
          if (idValue != null && !"".equals(idValue.trim()) && idValue.startsWith("#")) {
            idValue = idValue.substring(1);
            if (idValue.trim().length() > 0) {
              idTypeIdentifiers.add(new DefaultIDTypeIdentifier(idValue, false));
            }
          }
        }
      }
    }
    
    return idTypeIdentifiers.isEmpty() ? null : idTypeIdentifiers;
  }
  
  /**
   * @see ro.sync.ecss.extensions.api.link.IDTypeRecognizer#locateIDType(java.lang.String, ro.sync.contentcompletion.xml.Context, java.lang.String, java.lang.String, java.lang.String, ro.sync.ecss.extensions.api.link.IDTypeIdentifier, short)
   */
  @Override
  public int[] locateIDType(String systemID, Context context, String attrName, String attrNs,
      String attributeValue, IDTypeIdentifier idIdentifier, short mode) {
    
    int[] idLocation = null;
    
    if ((mode  & MODE_LOCATE_DECLARATIONS) != 0) {
      // xml:id declaration
      if("id".equals(attrName)) {
        idLocation = new int[] {0, attributeValue.length()};
      }
    }
    
    if ((mode  & MODE_LOCATE_REFERENCES) != 0) {
      if("target".equals(attrName)) {
        Stack<ContextElement> elementStack = context.getElementStack();
        if(!elementStack.isEmpty()) {
          String idValue = idIdentifier.getValue();
          String textToFind = "#" + idValue;
          int indexOf = attributeValue.indexOf(textToFind);
          while (indexOf >= 0) {
            if(indexOf + textToFind.length() == attributeValue.length() || 
                attributeValue.charAt(indexOf + textToFind.length()) == ' ') {
              idLocation = new int[] { indexOf + 1, indexOf + 1 + idIdentifier.getValue().length() };
            }
            if (idLocation != null) {
              break;
            } else {
              indexOf = attributeValue.indexOf(textToFind, indexOf + textToFind.length());
            }
          }   
        }
      }
    }
    return idLocation;
  }
  /**
   * @see ro.sync.ecss.extensions.api.link.IDTypeRecognizer#isDefaultIDTypeRecognitionAvailable()
   */
  @Override
  public boolean isDefaultIDTypeRecognitionAvailable() {
    return false;
  }
  /**
   * @see ro.sync.ecss.extensions.api.link.IDTypeRecognizer#isIDTypeRecognitionAvailable()
   */
  @Override
  public boolean isIDTypeRecognitionAvailable() {
    return true;
  }
}
So if your case resembles this case you may be able to implement it at framework level using this extension.
Regards,
Radu