Page 1 of 1

Adding an attribute to every instance of an element

Posted: Wed Sep 12, 2012 11:29 am
by tzirtzi
Hello all!

My apologies if this is a very basic and obvious question thoroughly answered elsewhere -- I've very little expertise in XML, and my attempts at looking for answers have so far been thwarted by a lack of understanding of the technical terms... My problem is as follows:

I have a series of XML documents (in TEI format), in which every word is contained in a <w>...</w> element, every sentence is contained in an <s>...</s> element, and all quoted speech is contained inside a <q>...</q> element. I need to view every <q> element one-by-one and add an attribute denoting speaker sex (something as simple as who="m" vs who="f" vs who="p" (plural)). The problem is that there are over 15,000 <q> elements, so I need to find a really efficient way to do this. What I was hoping is that there would be some way in Oxygen to view <q> elements one-by-one, perhaps in a concordance view, with all other xml elements hidden so that I can read the text easily, and just click a button on a form to select which value to add.

Is there any way to do this?

Thanks very much in advance!

Re: Adding an attribute to every instance of an element

Posted: Wed Sep 12, 2012 3:02 pm
by mihaela
Hi,

A simple way to see a list with all the "q" elements from your document, with all other elements filtered out is to use the Outline view (if it is not visible you can open it from Window menu -> Show View -> Outline) and write "q" in the filter field found above the Outline elements tree.

Another approach is to use the XPath field from the application toolbar (if you cannot find it right-click on the toolbar and check the "XPath" entry). If you write the "//q" expression in the XPath field and press "Enter", a results view will show up, containing a list with links to all "q" elements from your document.

Best regards,
Mihaela

Re: Adding an attribute to every instance of an element

Posted: Wed Sep 12, 2012 5:17 pm
by tzirtzi
Thanks very much for the reply!

Those methods will allow me to see a list of all of the q elements, but I'd also need to be able to do a couple of other things. Specifically, I'd need to be able to see the relevant section of the text without all the other xml bits. So for example, a block of speech might look like this:

Code: Select all

<q xml:id="q3"><w xml:id="w460" lemma="«" ana="#«">«</w> <s xml:id="s30" prev="s29"><w xml:id="w461" lemma="í" ana="#ao">Í</w> <w xml:id="w462" lemma="sá" ana="#faveo">þá</w> <w xml:id="w463" lemma="veiðistöð" ana="#nveo">veiðistöð</w> <w xml:id="w464" lemma="koma" ana="#sfg1en">kem</w> <w xml:id="w465" lemma="ég" ana="#fp1en">eg</w> <w xml:id="w466" lemma="aldregur" ana="#lkenvf">aldregi</w> <w xml:id="w467" lemma="á" ana="#aþ">á</w> <w xml:id="w468" lemma="gamall" ana="#lheesf">gamals</w> <w xml:id="w469" lemma="aldur" ana="#nkeþ">aldri</w> <w xml:id="w470" lemma="." ana="#.">.</w> </s><w xml:id="w471" lemma="»" ana="#»">»</w> </q>
As you can see, it's very awkward to read in this format. In order to read the text easily and so be able to make quick decisions about the who attribute on <q>, I need to be able to see it like this:

Code: Select all

<q xml:id="q3">« Í þá veiðistöð kem eg aldregi á gamals aldri . »</q>
Secondarily, it would be really useful to be able to set up an input form or something like that to speed up inputting the actual text who="m" or who="f" or who="p" over and over again.

Is there any way to achieve either of these things?

Thanks again :)

Re: Adding an attribute to every instance of an element

Posted: Thu Sep 13, 2012 10:53 am
by mihaela
Hi,

What you can do to be able to concentrate more on the semantics of the document is to switch to Author mode.
See here the description of the Author mode of the <oXygen/> XML Editor:
http://www.oxygenxml.com/wysiwyg_xml_editor.html

The Outline view and XPath toolbar fields are also available for the Author editing mode. To edit the attributes of the "q" elements more quickly you can write "q" in the Author Outline filter field and then for every entry from the Outline list invoke the "Edit attributes" action (right-click and choose the action from the contextual menu or press Alt+Enter).

In the next version of oXygen (14.1) you will be able to edit attributes in-place using visual controls (text fields or combo boxes). If you are interested in this feature and you want to try it now, you can send us an email to our support address support AT oxygenxml DOT com and we can send you an oXygen build containing this feature.

Best regards,
Mihaela

Re: Adding an attribute to every instance of an element

Posted: Thu Sep 13, 2012 5:11 pm
by tzirtzi
Thanks very much! Author mode does seem like a pretty good solution. I'll start doing the editing and see how well it works in practice!

Re: Adding an attribute to every instance of an element

Posted: Wed Dec 05, 2012 4:23 am
by StefanG
Mihaela, I have the same need. I want to add an attribute + value to a specific element.
That is, I want to add a scale="50" attribute to all image elements. Maybe it could be done with some regex s&r, but that's not really "stable". I would prefer a "real" XML operation. That is, I want xml-based, xpath based search and replace.
Do you know FrameSLT? It's a plugin for Adobe FrameMaker and makes complex node operations really easy: http://www.weststreetconsulting.com/WSC_FrameSLT.htm
Please check it, show it to George Bina and please, please implement something as powerful :-)

The way you suggest is nice, but not helpful if the number of elements you have to manipulate becomes bigger. No one really wants to change an Attribute on 10,000 elements. Probably not even on 100, frankly. And XSLT is often "too big" if you just need to make some quick & dirty changes.
So, if you know any better solution for now, please let me know.

By the way, you can also get a "Flat presentation mode of the filtered results" if you select it from the configuration wheel. This makes it even a tick faster to navigate through the elements. Also you can enter multiple, comma-separated element names. But there's a problem: entering "b" gives me all <b> elements, but also all <body> elements. Looks like a bug to me, especially as putting the element name e.g. in quotes does not help. Also you can enter wildcards that are expected to give this result ("b*" gives "b" and "body" as expected but so does "b" also!). Looks like a bug to me.

Thanks,
*Stefan.

Re: Adding an attribute to every instance of an element

Posted: Wed Dec 05, 2012 5:07 pm
by adrian
Hello,

Unfortunately only XML-based/XPath search (without replace) is available in Oxygen (Find > Find All Elements/Attributes or the XPath search combo). There are also the Find/Replace and Find/Replace in Files dialogs that are searching text, but are XML and XPath aware. You might be able to use these to accomplish what you want

What you want is somewhat beyond search/replace, since you actually want to insert/append content in a specific location from the XML document, not necessarily replace it. I've logged a feature request to our issue tracking tool to analyze and implement this use case in the long term.

Meanwhile, you could do this with Find/Replace with regexp and XPath in two steps:
1. for the elements that already have the "scale" attribute specified, update its value
2. for the elements that don't have the "scale" attribute, append it

1. Update value of scale attribute for image elements that already have it
Text to find: scale\s*=\s*".*?"
Replace with: scale="50"
XPath: //image/@scale
Regular Expression

Or, you can actually further tune this to:
Text to find: .*
Replace with: 50
XPath: //image/@scale
Regular Expression
Enable XML search options: Attribute values

2. Append "scale" attribute for image elements that don't have it
Text to find: <image
Replace with: $0 scale="50"
XPath: //image[not(@scale)]
Regular Expression


Regarding the outline filter, there is indeed an oversight in the design of the filter. It wasn't meant to filter exact matches, it always searches for partial matches. You can't specify an exact match, because it silently appends a * at the end of every pattern. That's why "b" and "b*" have the same result.
I've submitted an issue to allow this in a future version of Oxygen (probably with the quotes). We'll notify this thread when it becomes available.

Regards,
Adrian

Re: Adding an attribute to every instance of an element

Posted: Sat Dec 08, 2012 4:28 am
by StefanG
Thanks Adrian, that was helpful!

Re: Adding an attribute to every instance of an element

Posted: Thu Aug 15, 2013 1:02 pm
by Radu
Hi,

Just to update this thread, related to this request when searching in the Outline view:
But there's a problem: entering "b" gives me all <b> elements, but also all <body> elements.
In Oxygen 15.0 you can either search for a specific tag name using quotes to surround it or the Outline view has a drop-down cogwheel button which allows you to choose Filter returns exact match.

Regards,
Radu

Re: Adding an attribute to every instance of an element

Posted: Mon Jun 22, 2015 4:32 pm
by radu_pisoi
StefanG wrote: That is, I want to add a scale="50" attribute to all image elements. Maybe it could be done with some regex s&r, but that's not really "stable". I would prefer a "real" XML operation. That is, I want xml-based, xpath based search and replace.
I just wanted to let you know that the latest version (v17.0) of Oxygen contains the XML Refactoring tool that assists you with various refactoring tasks.

It helps you manage the structure of your XML documents and it includes a variety of operations, such as renaming, deleting, and inserting elements and attributes across a set of files. It is available in the Tools menu, the Project and DITA Maps Manager contextual menu.

In your case, you could use the 'Add/Change attribute' operation to add an attribute to a certain element.

You can read more details about this feature in our documentation:
http://www.oxygenxml.com/doc/versions/1 ... ments.html