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

Community Tip - Stay updated on what is happening on the PTC Community by subscribing to PTC Community Announcements. X

getting around xpaths in gentext

JeffStevenson
12-Amethyst

getting around xpaths in gentext

Hey folks,

I have a situation where I'm referencing an attribute value from the root node in a block that is getting formatted into a table with gentext. The problem is I lose the attribute value because XPaths do not work in gentext very well.

Consider the sample XML...

<root attr="foo">

<block>

<p> The value is <placeholder target="attr"/>.</p>

</block>

</root>

I have an XPath/Attribute set on placeholder to get the value of "attr" from the root node. The stylesheet is formatting <block> into a table. When these combine, I lose the value of attr in placeholder.

I've seen this done before, but can't remember how it is done. Appreciate any tips.

Thanks,

-Jeff

ACCEPTED SOLUTION

Accepted Solutions

Hi Jeff--

It would help to see the actual XPath you are using. With certain Styler things (notable page headers and footers), relative XPath doesn't work because there's not really a context element in the sense we usually think of it. That may be what's happening here. But in those cases, if you can use an absolute XPath (one that starts with "/"), then it often works.

--Clay

View solution in original post

6 REPLIES 6

Hi Jeff--

It would help to see the actual XPath you are using. With certain Styler things (notable page headers and footers), relative XPath doesn't work because there's not really a context element in the sense we usually think of it. That may be what's happening here. But in those cases, if you can use an absolute XPath (one that starts with "/"), then it often works.

--Clay

Hi Clay,

I've tried an XPath and and Attribute Content. Both of which equate to a relative path

Attribute Content

<_gte:Target lang="en"><_gte:AttributeContent occur="ancestor" attr="attr" elem="root"/></_gte:Target>

XPath

ancestor::root/@attr

The problem is that the XML could be nested into a map-like structure where many root tags could be present. I want the nearest root ancestor to the placeholder.

<map>

<root/>

<root/>

<root attr="foo">

<block>

<p> The value is <placeholder target="attr"/>.</p>

</block>

</root>

<root/>

</map>

So mapping direct may resolve to the incorrect root tag.

/root?/@attr

Is there a different way to write the Xpath that maps to the nearest ancestor without using relative paths?

Ah, I see. Well, to be honest, I'm not even sure that's the problem. It's something I've run into before, as I said regarding headers and footers, but I haven't seen it with tables before. So, the relative path thing may be something of a red herring. I don't think you will be able to map to a "nearest ancestor" without using a relative path--the whole concept of "nearest ancestor" is pretty much relative by definition, so I don't see a way around that.

As a matter of fact, now that I look at your original posting again, I suspect the problem has more to do with your use of semantic tables than relative paths. I wonder if the semantic table transformation is generating content that loses the original context, making the relative path break.

OTOH, I was able to get something like this working with a simple variation of the axdocbook stylesheet. I configured an element as a custom (semantic) table, put content inside it that uses gentext to get the XPathString "ancestor::section[1]/@role" (where the target element is outside the semantic table markup), and it seems to work just fine in both print and screen output.

<Condition>

<Tests>

<AttributeTest attributeName="role"/></Tests>

<BaseProperties>

<GeneratedText>

<AddBefore><_sfe:BeforeOrAfterText><_gte:Translate translate="off"

id="A1c7b28e5-aca2-4884-ab9b-f334e8dbddf2"><_gte:Target lang="en"

><_gte:XPathString expr="ancestor::section[1]/@role"/></_gte:Target

></_gte:Translate></_sfe:BeforeOrAfterText></AddBefore>

</GeneratedText>

</BaseProperties>

</Condition>

What version of Editor are you using? I wonder if maybe this was a bug in semantic table handling that got fixed or something like that.

Hi Clay,

I think your first assessment was correct. When I use an absolute path, it finds the value just fine. This would be great if I didn't have the hurdle of locating the nearest ancestor when in the map structure.

I don't know of a way to find an ancestor with a relative path. I'm dong some playing with predicates, but no luck so far. I may have to do a source edit to save the attr value into a variable then place it when the gentext is built.

Thanks for the help.

-Jeff

Hi Jeff--

You said, "I don't know of a way to find an ancestor with a relative path". XPath provides the "ancestor" axis for exactly this purpose. To find the nearest ancestor "root" element and get its @attr value, try this:

ancestor::root[1]/@attr

It looks like maybe you are trying to get the name of the target element attribute to extract based on the value of an attribute on the source element. So, if you had

<root attr="foo" otherattr="bar">

<block>

<p> The value is <placeholder target="otherattr"/>.</p>

</block>

</root>

you would want it to say "The value is bar." Do I understand that correctly?

If so, that's going to be really hard. In XSLT you can do this sort of thing by using the current() function, but that's an XSLT function rather than XPath, so it doesn't work in Styler XPath string expressions.In that case, you will almost certainly need source edits.

--Clay

Hi Clay,

We resolved this by doing a Javascript source edit on it. Ended up being much easier than the time I wasted trying to find an XPath solution.

Thanks for the assistance on the absolute paths in gentext. That was the root cause.

-Jeff

Announcements

Top Tags