suroundInFragment method

Oxygen general issues.
np18
Posts: 13
Joined: Tue Mar 16, 2021 10:01 pm

suroundInFragment method

Post by np18 »

Hi,
I have the following TEI XML structure (simplified)

Code: Select all

<list>
  <item><label someAtr="somevalue" someOtherAtr="othervalue" >some <g>m</g>ixed content</label></item>
  <item><label someAtr="somevalue" someOtherAtr="othervalue">some <g>m<unclear>ixed content</unclear></label></item>
  ...
</list>
I want to surround the mixed content (Roman numerals mixed with some other symbols and elements) with a <num> element:

Code: Select all

<list>
  <item><label someAtr="somevalue" someOtherAtr="othervalue" ><num>some <g>m</g>ixed content</num></label></item>
  <item><label someAtr="somevalue" someOtherAtr="othervalue"><num>some <g>m<unclear>ixed content</unclear></num></label></item>
  ...
</list>
This needs to be done programmatically from an authorOperation, as the value of the numeral and other stuff is computed and inserted.

I try to insert <num> by using

Code: Select all

authorAccess.getDocumentController().surroundInFragment("<num></num>", labelNode.getStartOffset(), labelNode.getEndOffset());
Which surrounds the <label> element with an <num> element. To do it the other way around, I tried to compute the (changing) length of the <label> start tag and add the value to the labelNode.getStartOffset(). Then the fixed length of the closing tag </label> = 8 is subtracted from the EndOffset.

This is the line I use for the insertion:

Code: Select all

authorAccess.getDocumentController().surroundInFragment("<num></num>", labelNode.getStartOffset() + startTagLength, labelNode.getEndOffset() - 8);
This is how I compute the starting tag length somewhere earlier in the code (in a for loop looping through a nodelist found by xpath):

Code: Select all

  	AuthorElement labelElement = (AuthorElement) labelNode;
	    	
    	// Get length of the element's name, add 2 for angle brackets.
    	int startTagLength = labelElement.getName().length() + 2; // +2 for '<' and '>'
	    	
    	// Iterate over all attributes and add their lengths
    	int attrCount = labelElement.getAttributesCount();
    	for (int i = 0; i < attrCount; i++) {
    	    // Get attribute name, add 1 for equals sign, get value, add 2 for quotes, add 1 for leading space.
    	    String attrName = labelElement.getAttributeAtIndex(i);
    	    String attrValue = labelElement.getAttribute(attrName).getValue();
    	    startTagLength += attrName.length() + attrValue.length() + 1 + 2 + 1;
    	}
If I use this operation in Oxygen, it only works if I leave the elements offset untouched, producing <num><label></label></num>. The moment I add and subtract the computed offset, the action does something (because oxygen freezes for a second), but produces no outcome or error message whatsoever.

Questions:
- Is there a more elegant way to do this using oxygenxml API?
- Why does my code have no effect?

Any help would be greatly appreciated (as always!)

Best,
Michael
alex_jitianu
Posts: 1009
Joined: Wed Nov 16, 2005 11:11 am

Re: suroundInFragment method

Post by alex_jitianu »

Hello,

There are a couple aspects to consider:
1. In the model, each start tag and end tag has just one special marker character.
2. An AuthorNode start offset points to the start marker and the end offset points to the end marker, as depicted in the link above
3. surroundInFragment() endOffset is inclusive, so that offset also gets surrounded.

To surround the contents of the label element, this should do:

Code: Select all

authorAccess.getDocumentController().surroundInFragment("<num></num>", labelNode.getStartOffset() + 1, labelNode.getEndOffset() - 1);
Please note that the above code will be in trouble for an empty label element (labelNode.getStartOffset() + 1 = labelNode.getEndOffset()) in which case you should just insert at labelNode.getStartOffset() + 1

Best regards,
Alex
np18
Posts: 13
Joined: Tue Mar 16, 2021 10:01 pm

Re: suroundInFragment method

Post by np18 »

Dear Alex,
thanks, that works! I misunderstood the image, but now it makes perfect sense. The empty element is no problem because in this case, nothing will be inserted.
Thanks for the help and explanation!
Last edited by np18 on Wed May 17, 2023 10:14 am, edited 1 time in total.
Post Reply