INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Get Path of Attribute

Get Path of Attribute

(OP)
Is there a way to get the path of an attribute?

In otherwords, if I have worked my way down to an attribute in some node, is there some way to get the path of that attribure or node name based on a current location.

I am trying to get a path to add to my translation of the path of a node.

Something like:

//RESPONSE/VMETHODS/SALES[@SequenceId="0"]/ADJUSTMENT[@_Type="Storage"]/@_Description

which I might get from something like:

<xsl:value-of select="path"/>

Thanks,

Tom

RE: Get Path of Attribute

(OP)
I know that I can get the path looking at "ancestor::*".  But how can I get that returned?

If I have the following:

CODE

  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/*">
    <xsl:copy>
      <xsl:apply-templates select="METHODS/COMPARISON">
        <xsl:with-param name="reportName" select="REPORT/@MajorFormType"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <!-- Now we handle the other sections after the DATA section -->

  <xsl:template match="COMPARISON">
    <xsl:param name="reportName"/>
    <xsl:apply-templates>
      <xsl:with-param name="reportName" select="$reportName"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="SALE">
    <xsl:param name="reportName"/>
    <xsl:variable name="temp" select="../@ID"/>
    <xsl:value-of select="../@ID"/>    <!-- Works Here -->
    <xsl:for-each select="@*">
      <form>
        <var>
          <xsl:value-of select="$temp"/>
        </var>
        <ID>
          <xsl:value-of select="../../@ID"/>  <!-- Does Not Work Here -->
        </ID>
        <section>
          <xsl:text>0</xsl:text>
        </section>
        <formName>
          <xsl:value-of select="$reportName"/>
        </formName>
        <tagName>
          <xsl:value-of select="name()"/>
        </tagName>
        <value>
          <xsl:value-of select="."/>
        </value>
        <path>
          ancestor::*      <!--show as //REPSONSE/METHODS/COMPARISON/SALE -->
        </path>
      </form>
    </xsl:for-each>
    <xsl:apply-templates>
      <xsl:with-param name="reportName" select="$reportName"/>
    </xsl:apply-templates>
  </xsl:template>
 </xsl:stylesheet>

In the debugger, it might show ancester::*[4] which when expanded will show all the above nodes.

Is there a statement that will take the "ancester::*" and return the string as shown?

Thanks,

Tom

RE: Get Path of Attribute

(OP)
I tried to do the following:

CODE

        <path>
          <xsl:for-each select="ancestor-or-self::*">
            <xsl:value-of select="."/>
            <xsl:if test="position() != last()">
              <xsl:value-of select="."/>
            </xsl:if>
          </xsl:for-each>
        </path>

And the code seems to work but will not print out the value.  If I look at the "." in the debugger, for each iteration - it shows the correct values (one of the node names in the path).

But when I look at the xml it created it just puts a bunch of spaces and line feed for these values and no node names.

Why is that?

Thanks,

Tom

 

RE: Get Path of Attribute

Tom,

<xsl:value-of select="."/> is returning the value of the node, which for most of the nodes is whitespace. While the node name of the context node may be seen in the debugger, the node name is not the value of the context node.  You might try select="local-name()" if I understand what you are trying to accomplish.

I think then you will find that the node names on the ancestor-or-self axis will appear in the opposite of your desired order.  You will probably need to use recursion (such things eventually happen in the life of XSLT developers).  Here are some recursion examples.  After you work through an example or two, try writing your own.  The called template would probably have two parameters, the current value of the string you wish to output and the next node to output (..). The called template would continue to concatenate the current node's information to the beginning of the string and call itself until the parent node is null, which means you are at the document root, and you can then output the string (with an xsl:value-of).

Sounds daunting if you are not familiar with recursion, but give it a try.  If you are serious about using XSLT, cracking your first use of recursion is a major step in knowing how to use this tool.

Tom Morrison
Micro Focus

RE: Get Path of Attribute

(OP)
That does explain the spaces - thanks.

I did look further and did see information on recursion when I was trying to figure out how to return a value from a call-template.

I will look at the examples to get a better idea on how it works.

But I did find a way to do this which is similar to what you mentioned.  This will get me the path with slashes between them in the correct order.

CODE

      <path>
        <xsl:for-each select="ancestor-or-self::*">
          <xsl:value-of select="name()" />
          <xsl:text>/</xsl:text>
        </xsl:for-each>
      </path>

Thanks,

Tom

RE: Get Path of Attribute

Hmmm.  That's not what I would expect.

The XSLT specification states that the ancestor-or-self axis should present the nodes in reverse document order.  That is:
ancestor-or-self::*[1] is the context node,
ancestor-or-self::*[2] is the parent of the context node,
ancestor-or-self::*[3] is the grandparent of the context node,
...
ancestor-or-self::*[last()] is the document root.

Thus, I would expect your xsl:for-each loop to list the elements in reverse order.
 

Tom Morrison
Micro Focus

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close