2

Possible Duplicate:
Generate/get xpath from XML node java

This is a follow-on question from a previous question I’ve asked, (I’ve decided to ask as a separate question, as the previous seems to be getting too big).

I’ve got the following XSLT, which allows me to transform a specified XML String into a set of XPath expressions:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="text()"/>

    <xsl:template match="*[not(*)]">
        <xsl:for-each select="ancestor-or-self::*">
            <xsl:value-of select="concat('/',local-name(),'[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')"/>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>
        <xsl:apply-templates select="node()"/>
    </xsl:template>

</xsl:stylesheet>

For example, the XML String:

<ns1:create xmlns:ns1='http://predic8.com/wsdl/material/ArticleService/1/'>
    <article xmlns:ns1='http://predic8.com/material/1/'>
        <name />
        <description />
        <price xmlns:ns1='http://predic8.com/common/1/'>
            <amount />
            <currency xmlns:ns1='http://predic8.com/common/1/‘>AUD</currency>
        </price>
        <id xmlns:ns1='http://predic8.com/material/1/‘>1</id>
    </article>
    <article xmlns:ns1='http://predic8.com/material/2/'>
        <name xmlns:ns1='http://predic8.com/material/2/'>some name</name>
        <description xmlns:ns1='http://predic8.com/material/2/'>some description</description>
        <price xmlns:ns1='http://predic8.com/common/2/'>
            <amount xmlns:ns1='http://predic8.com/common/2/'>00.01</amount>
            <currency xmlns:ns1='http://predic8.com/common/2/'>USD</currency>
        </price>
        <id xmlns:ns1='http://predic8.com/material/2/'>2</id>
    </article>
</ns1:create>

Would get transformed into:

/create[1]/article[1]/name[1]
/create[1]/article[1]/description[1]
/create[1]/article[1]/price[1]/amount[1]
/create[1]/article[1]/price[1]/currency[1] , AUD
/create[1]/article[1]/id[1] , 1
/create[1]/article[2]/name[1]
/create[1]/article[2]/description[1]
/create[1]/article[2]/price[1]/amount[1]
/create[1]/article[2]/price[1]/currency[1]
/create[1]/article[2]/id[1]

My question: How, can I modify the XSLT so that I can also select and append the current node’s text value. Noting also that, as I've illustrated in the sample XML file supplied, some nodes may not contain text values, etc.

So for the sample above, I would expect something like (e.g. comma-separated output):

/create[1]/article[1]/name[1] , 
/create[1]/article[1]/description[1] , 
/create[1]/article[1]/price[1]/amount[1] , 
/create[1]/article[1]/price[1]/currency[1] , 
/create[1]/article[1]/id[1] , 
/create[1]/article[2]/name[1] , some name
/create[1]/article[2]/description[1] , some description
/create[1]/article[2]/price[1]/amount[1] , 00.01
/create[1]/article[2]/price[1]/currency[1] , USD
/create[1]/article[2]/id[1] , 2
6
  • The answer is provided here: stackoverflow.com/questions/4746299/… Just use it. I know applications for testing XSLT that use this as the core for tests of any XSLT transformation. Commented Jul 19, 2012 at 15:28
  • Thanks, that post is quite brilliant... wish I would have known about it earlier! Commented Jul 19, 2012 at 15:41
  • 1
    @Kev♦ Thank you for deleting my answer ... Besides closing the question, you could at least specify which is the duplicate question -- otherwise any interested reader wouldn't know where to look. I hope this is just a casual omission from your side and not a display of pedantic formalism with lack of thought -- which I hope no moderator should ever exhibit. If, unfortunately, this comment is embarassing to you, I'll understand if you delete it. So will the people who have read this comment :) Commented Jul 19, 2012 at 18:32
  • 2
    @DimitreNovatchev There's a link at the top of the page that goes to the original question. Kev didn't omit anything. Commented Jul 19, 2012 at 20:07
  • 1
    @DimitreNovatchev - your accepted answer linked to another question with an accepted answer. That means it's a duplicate, it's standard procedure that we close these questions as dupes and delete such answers as yours. Next time just flag as a duplicate. Thanks. Commented Jul 19, 2012 at 22:39

1 Answer 1

0

It should as simple as adding a select=./text() at the appropriate node, or have I missed something subtle in your question?

<xsl:template match="*[not(*)]">
    <xsl:for-each select="ancestor-or-self::*">
        <xsl:value-of select="concat('/',local-name(),'[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')"/>
    </xsl:for-each>
    <xsl:text> , </xsl:text>
    <xsl:value-of select="./text()"/>
    <xsl:text>&#xA;</xsl:text>
    <xsl:apply-templates select="node()"/>
</xsl:template>

Output:

/create[1]/article[1]/name[1] , 
/create[1]/article[1]/description[1] , 
/create[1]/article[1]/price[1]/amount[1] , 
/create[1]/article[1]/price[1]/currency[1] , AUD
/create[1]/article[1]/id[1] , 1
/create[1]/article[2]/name[1] , some name
/create[1]/article[2]/description[1] , some description
/create[1]/article[2]/price[1]/amount[1] , 00.01
/create[1]/article[2]/price[1]/currency[1] , USD
/create[1]/article[2]/id[1] , 2
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.