Skip to main content
1-Visitor
August 17, 2012
Question

FOSI: It's not possible to savetext an element and fill an attribute with variable content ....

  • August 17, 2012
  • 10 replies
  • 2315 views
For example, one can't make one of the following savetexts work:

<e-i-c gi="dtdelement"...&lt;br"/><savetext textid="myvar1.txt" conrule="!&lt;myelement&lt;br /&gt;myattr="!,#CONTENT(dtdattr),!"&gt;!,#CONTENT,!&lt;/myelement&gt;!" placemnt="before">
<savetext textid="myvar2.txt" conrule="\&lt;myelement&lt;br /&gt;myattr="\,#CONTENT(dtdattr),\"&gt;\,#CONTENT,\&lt;/myelement&gt;\" placemnt="before">

dtdattr is CDATA and the possible values are endless ...


Later I want to <usetext conrule="myvarX.txt"&lt;br"/>

Or am I wrong and there is a magic conrule recipe I'm missing that will
achieve this?

--
Paul Nagai

    10 replies

    1-Visitor
    August 18, 2012
    Hey, Paul...

    There is a feature which, as far as I can tell, is undocumented, but is
    used by Styler to do something like this. It seems to be supported in
    later 5.3 versions (M210 has it, but M010 does not appear to), some 5.4
    (M050 has it) and all 6.0 versions. You can probably see if it's supported
    in your version by searching for "SETATTR" in
    packages\main\_styleexportfosi.acl, which is the code that transforms a
    Styler sheet into a FOSI.

    I haven't tested this, but based on how Styler uses it, something like this
    may work:

    <savetext textid="myvar1.txt"&lt;br"/>conrule='!<myelement>!,#SETATTR(myattr,@dtdattr)#ENDSETATTR,#CONTENT,!</myelement>!'
    placemnt="before">

    The part after the comma in the #SETATTR is an XPath, so you should be able
    to put just about anything into the attribute with that construct.

    -Brandon 🙂


    naglists1-VisitorAuthor
    1-Visitor
    August 18, 2012
    Oooh, undocumented FOSI tricks give me itchy fingers. I might have to go
    play with this today.

    Thanks, Brandon.


    On Sat, Aug 18, 2012 at 1:03 AM, Brandon Ibach <
    brandon.ibach@single-sourcing.com> wrote:

    > Hey, Paul...
    >
    > There is a feature which, as far as I can tell, is undocumented, but is
    > used by Styler to do something like this. It seems to be supported in
    > later 5.3 versions (M210 has it, but M010 does not appear to), some 5.4
    > (M050 has it) and all 6.0 versions. You can probably see if it's supported
    > in your version by searching for "SETATTR" in
    > packages\main\_styleexportfosi.acl, which is the code that transforms a
    > Styler sheet into a FOSI.
    >
    > I haven't tested this, but based on how Styler uses it, something like
    > this may work:
    >
    > <savetext textid="myvar1.txt"&lt;br"/>> conrule='!<myelement>!,#SETATTR(myattr,@dtdattr)#ENDSETATTR,#CONTENT,!</myelement>!'
    > placemnt="before">
    >
    > The part after the comma in the #SETATTR is an XPath, so you should be
    > able to put just about anything into the attribute with that construct.
    >
    > -Brandon 🙂
    >
    >
    >
    naglists1-VisitorAuthor
    1-Visitor
    August 20, 2012
    Thanks for the pointer, Brandon. 6.0 m010 does support #SETATTR. And, I
    think I am close. Hopefully I just need some XPath help addressing
    namespaced elements ... or, I fear, the namespaced attributes are "hidden"
    from the #SETATTR code somehow.

    Specifically, I am trying to capture the value of atidlm:targetLocator on
    element atidlm:resourcepair. I can use standard FOSI fillvals to capture
    and save other atidlm:xxxxx attributes on atidlm:resourcepair. But I can't
    get #SETATTR to access it.

    The following will produce a working link leveraging an existing
    <my_link_element> e-i-c:

    <savetext textid="my_link.txt" conrule="!&lt;my_link_element type="http"&gt;!,#&lt;br /&gt;SETATTR(target,"&lt;a style="COLOR: blue; TEXT-DECORATION: underline" target="_BLANK" href="http://google.com")#ENDSETATTR,my_targetName.txt,!&lt;/my_link_element&gt;!" &quot;=">http://google.com")#ENDSETATTR,my_targetName.txt,!</my_link_element>!'
    placemnt="before">

    But this does not:
    <savetext textid="my_link.txt" conrule="!&lt;my_link_element type="http"&gt;!,#&lt;br /&gt;SETATTR(target,@atidlm:targetLocator)#ENDSETATTR,my_targetName.txt,!&lt;/my_link_element&gt;!" <br="/>placemnt="before">

    Does XPath require something magical to "see" an attribute in the atidlm
    namespace?

    I notice that much of the code using this (maybe all) uses the string
    function like this:
    #SETATTR(myattr,string(@dtdattr))#ENDSETATTR

    It didn't help in my case.

    Any thoughts?

    On Sat, Aug 18, 2012 at 1:03 AM, Brandon Ibach <
    brandon.ibach@single-sourcing.com> wrote:

    > Hey, Paul...
    >
    > There is a feature which, as far as I can tell, is undocumented, but is
    > used by Styler to do something like this. It seems to be supported in
    > later 5.3 versions (M210 has it, but M010 does not appear to), some 5.4
    > (M050 has it) and all 6.0 versions. You can probably see if it's supported
    > in your version by searching for "SETATTR" in
    > packages\main\_styleexportfosi.acl, which is the code that transforms a
    > Styler sheet into a FOSI.
    >
    > I haven't tested this, but based on how Styler uses it, something like
    > this may work:
    >
    > <savetext textid="myvar1.txt"&lt;br"/>> conrule='!<myelement>!,#SETATTR(myattr,@dtdattr)#ENDSETATTR,#CONTENT,!</myelement>!'
    > placemnt="before">
    >
    > The part after the comma in the #SETATTR is an XPath, so you should be
    > able to put just about anything into the attribute with that construct.
    >
    > -Brandon 🙂
    >
    >
    >
    naglists1-VisitorAuthor
    1-Visitor
    August 20, 2012
    Ok. This is just wrong. I dropped the namespace prefix and tossed this Hail
    Mary:

    <savetext textid="my_link.txt" conrule="!&lt;my_link_element type="http"&gt;!,#&lt;br /&gt;SETATTR(target,@targetLocator)#ENDSETATTR,my_targetName.txt,!&lt;/my_link_element&gt;!" <br="/>placemnt="before">

    The SOB worked. Again, that's just wrong. But, uh, ok, I'll take it.



    18-Opal
    August 20, 2012
    I've noticed wonkiness in handling of namespaced elements and attributes
    in Arbortext's XPath handler as well. I can't really explain why your
    approach here worked--I agree it's not correct behavior, but I also
    understand not looking a gift horse in the mouth. 🙂



    For future reference, my usual workaround when I need to handle
    namespaced stuff is to use the local-name() function, something like
    this:



    SETATTR(target,@*[local-name()='targetLocator'])



    --Clay





    Clay Helberg

    Senior Consultant

    TerraXML


    August 20, 2012
    SHHHHHHHHH!! If you mention that it isn't correct behavior, they'll fix your gift horse in a couple of M-releases 🙂
    1-Visitor
    August 20, 2012
    Yeah, I wouldn't expect that to work, either, but no complaints as long as
    the job gets done, right? 🙂

    As for a sort-of explanation, the "real" name of a namespaced attribute is
    the actual namespace URI combined with the local name. The prefix is just
    a syntactic shortcut. So, the XPath engine needs to be able to resolve
    that shortcut to the same URI. You might expect that it could just get
    this information from the document you're navigating, but that can prove
    problematic, as your style sheet would not work if some document used a
    different prefix for the same namespace. So, the usual rule is that the
    "host" of the XPath engine (FOSI, in this case) provides the means to
    define prefixes, though I'm not sure, offhand, what the rules are on that.

    All that said, I think Clay's approach is the safe bet. You could go one
    step further and do something like:

    @*[name()='atidlm:targetLocator']

    or, if you're at all worried that the prefix might ever be different:

    @*[local-name()='targetLocator' and namespace-uri()='
    naglists1-VisitorAuthor
    1-Visitor
    August 20, 2012
    Odd. On a different e-i-c the @targetLocator syntax didn't work. Clay's
    suggested syntax, however, did.

    Now I'm using #SETATTR(ID,@*local-name()="targetXmlId"])#ENDSETATTR which I
    declare as CORRECT so no changing that in future m-releases, please! 🙂

    I didn't test Brandon's variations ... but prolly they work, too.

    Thanks, everyone. Nice trick!

    Hey, Suzanne: This adds up to another page in your book! 🙂


    On Mon, Aug 20, 2012 at 1:39 PM, Brandon Ibach <
    brandon.ibach@single-sourcing.com> wrote:

    > Yeah, I wouldn't expect that to work, either, but no complaints as long as
    > the job gets done, right? 🙂
    >
    > As for a sort-of explanation, the "real" name of a namespaced attribute is
    > the actual namespace URI combined with the local name. The prefix is just
    > a syntactic shortcut. So, the XPath engine needs to be able to resolve
    > that shortcut to the same URI. You might expect that it could just get
    > this information from the document you're navigating, but that can prove
    > problematic, as your style sheet would not work if some document used a
    > different prefix for the same namespace. So, the usual rule is that the
    > "host" of the XPath engine (FOSI, in this case) provides the means to
    > define prefixes, though I'm not sure, offhand, what the rules are on that.
    >
    > All that said, I think Clay's approach is the safe bet. You could go one
    > step further and do something like:
    >
    > @*[name()='atidlm:targetLocator']
    >
    > or, if you're at all worried that the prefix might ever be different:
    >
    > @*[local-name()='targetLocator' and namespace-uri()='
    1-Visitor
    August 20, 2012
    I know it! Curse you! 😉

    Suzanne


    1-Visitor
    August 24, 2012
    Hmmm, I see Brandon is to "blame." 😉 Actually, I'm delighted to know about the undocumented #SETATTR feature -- I could have used it myself in the past!

    Now it is documented. PDF is attached. All comments welcome.

    BTW: If anyone knows of any other undocumented features I should put in the book, please let me know asap.

    Thanks!
    Suzanne Napoleon
    www.FOSIexpert.com
    "WYSIWYG is last-century technology!"