cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - New to the community? Learn how to post a question and get help from PTC and industry experts! X

How to find an empty attribute in Arbortext?

nbonanno-2
2-Guest

How to find an empty attribute in Arbortext?

Hello-

I can't get Find/Replace attributes to find attributes that are null (empty).  Is there a trick to that?  Or a way to do it from the command line?  Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions

Hi Nancy--

OK, great. So to answer your follow-up questions:

  1. Yes, to limit the search to specific elements, simply replace "*" in the XPath expression with an explicit tag name. For example, to find <cite.state.law> elements without a ref attribute, you would use: "//cite.state.law[not(@ref)]". (It gets a little trickier if you are using namespaces, but there are ways around that.)
  2. To go to each instance, see my original reply above. The strategies outlined there (via either ACL function or command line commands) should work fine once you get the XPath expression tweaked to collect just the items you are interested in.

Note that XPath is extremely powerful, and can let you specify complex element constraints. For example, if you wanted to get <cite.state.law> elements with no "ref" attribute, but only if they are inside <cite.state> elements where the "state.name" attribute is "MN", you could do something like this:

     //cite.state[@state.name="MN"]//cite.state.law[not(@ref)]

So, if you get to know XPath well, you can be very precise in selecting exactly the elements you want (and only those elements). There are plenty of tutorials online to help you learn to use the full power of XPath. A quick Google search should turn up lots of good hits.

--Clay

View solution in original post

10 REPLIES 10

I had this same question. If you have a support contract with PTC, see https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS109701&art_lang=en&posno=1&q=CS109701&source=search

In an RDE, you can also enter in the command bar at the bottom :

find -m "<indexterm><indexterm> " or you can also do find -m "<indexterm></indexterm>" this will search for empty indexterm elements.

Bryon

Thanks so much for taking the time to respond.  Unfortunately, I can't use that link.  And I think you are showing me how to find empty tags.  I need to find empty attributes.

For example, I have a user who has 200 footnotes in a document and in most of them, the only.in attribute is set to !print.  (Hence, those footnotes will not appear in the print product; only the electronic product.)  But in a handful of footnotes, the only.in element did not get input so they are blank.  Is there a way he can basically say "take me to each footnote that does not have anything in the only.in attribute?"

Thanks again.

Hi Nancy--

You can do this via XPath in a script, or you could break it down into multiple command-line steps.

A script function would look something like this:

function findEmptyAttributes(attrname) {

local oids, o;

xpath_nodeset(oids, "//*[@" . attrname . " = '']");

for (o in oids) {

   # do something useful here, e.g. remove the empty attr

   oid_delete_attr(oids[o], attrname);

}

}

Or, if you want to use the command line, do something like this:

     xpath_nodeset($oids, "//*[@foo='']");

This will fill the array $oids with pointers to the elements with empty attribute values for attribute "foo" (adjust as necessary for your desired attribute name). You can see how many hits you got with the count() function:

     response("Found " . count($oids) . " empty attr values");

Then you can go through the list one by one, referencing it by index in the array. For example, to go to the first hit, use

     goto_oid($oids[1]);

To go to the second, use goto_oid($oids[2]), and so on.

--Clay

Embarrassingly, implementing a script is a bit over my head, plus the developers probably wouldn't let me.  I'm just a support person/trainer.

I tried the command...  

xpath_nodeset($oids, "//*[@country.code='']");    (country.code being an attribute of <county> I emptied) 


...but the response command returned 0 empty elements.  Am I doing something wrong?  Or maybe my system is setup differently?


Thanks.


Hi Nancy--

Well, the XPath looks OK, assuming you have ruled out misspelling the attribute name. Can you paste a copy of the markup you are trying to match, i.e. the instance you modified with an empty attribute value?

--Clay

Sorry I dropped out.  Sickness, vacation, blah blah.  I will get you something to look at.  (My developers say we can't search for something that isn't there. 

That basically, if they didn't add the attribute then the attribute is not on the tag AT ALL...it's not that it is there, but empty...)

Well, you are talking about two different things now. Not having an attribute value at all is different from having an empty attribute value.

If you are trying to find empty attribute values (where the attribute is specified but the value is empty), then the XPath above should work.

If you are trying to find elements that do not have a specific attribute, then you need something different, which would look like this:

xpath_nodeset($oids, "//*[not(@country.code)]");


If you want to catch both types of elements in one go, you could use something like this:

xpath_nodeset($oids, "//*[not(@country.code) or (@country.code='')]");


--Clay

Okay, neat!  Getting closer! 

I used xpath_nodeset($oids, "//*[not(@ref)]");

...after removing the ref attribute from a <cite.state.law> tag and then used response("Found " . count($oids) . " empty attr values"); and it returned 287...because LOTS of tags don't have the ref attribute because they don't use the ref attribute.  Is there a way to say only if [not(@foo)] on a specific tag type?

Also counting them is great, but will there be a way to GO to each of these tags-with-the-missing-attribute?  Thanks again for this amazing help.

Hi Nancy--

OK, great. So to answer your follow-up questions:

  1. Yes, to limit the search to specific elements, simply replace "*" in the XPath expression with an explicit tag name. For example, to find <cite.state.law> elements without a ref attribute, you would use: "//cite.state.law[not(@ref)]". (It gets a little trickier if you are using namespaces, but there are ways around that.)
  2. To go to each instance, see my original reply above. The strategies outlined there (via either ACL function or command line commands) should work fine once you get the XPath expression tweaked to collect just the items you are interested in.

Note that XPath is extremely powerful, and can let you specify complex element constraints. For example, if you wanted to get <cite.state.law> elements with no "ref" attribute, but only if they are inside <cite.state> elements where the "state.name" attribute is "MN", you could do something like this:

     //cite.state[@state.name="MN"]//cite.state.law[not(@ref)]

So, if you get to know XPath well, you can be very precise in selecting exactly the elements you want (and only those elements). There are plenty of tutorials online to help you learn to use the full power of XPath. A quick Google search should turn up lots of good hits.

--Clay

Oh my gosh, oh my gosh this worked!  And it is so awesome!  I'm going to have a very happy user. 

And I will definitely go out and learn more about XPath because that was amazing.

Thank you so very much for your help!

Top Tags