Solved

how to get the content of a section from a node in xml to xml conversion using xslt 1.0

Posted on 2011-09-12
6
330 Views
Last Modified: 2013-11-18
My xml is attached. I am trying to acheive this


                                    <misbn>
                                          9780470697900; 9780470512661; 9780470059081; 9780470697870
                                    </misbn>
the rules are

Content of <dc:identifier_isbn> AND
Content of the last section after the final / of the <dc:identifier_dbid> which contains text "dx.doi.org". If more than one of these use first only.
Separate entries with semicolon and a space

Example:
<dc:identifier_isbn>9780470697900</dc:identifier_isbn>
<dc:identifier_isbn>9780470512661</dc:identifier_isbn>
<dc:identifier_isbn>9780470059081</dc:identifier_isbn>
<dc:identifier>http://dx.doi.org/10.1002/9780470697870</dc:identifier>

"9780470697900; 9780470512661; 9780470059081; 9780470697870"
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <rdf:Description>
 <dc:identifier>http://www.myilibrary.com?id=234220</dc:identifier>
    <dc:identifier>http://www.netlibrary.com/urlapi.asp?action=summary&amp;v=1&amp;bookid=323900</dc:identifier>
    <dc:identifier>http://catdir.loc.gov/catdir/toc/ecip0719/2007022434.html</dc:identifier>
    <dc:identifier_isbn>9780470697900</dc:identifier_isbn>
    <dc:identifier_isbn>9780470512661 </dc:identifier_isbn>
    <dc:identifier_isbn>9780470059081 </dc:identifier_isbn>
    <dc:identifier_isbn></dc:identifier_isbn>
    <dc:identifier_isbn></dc:identifier_isbn>
    <dc:identifier_isbn></dc:identifier_isbn>
    <dc:identifier_isbn></dc:identifier_isbn>
    <dc:identifier_dbid>http://site.ebrary.com/id/10297565</dc:identifier_dbid>
    <dc:identifier_dbid>http://dx.doi.org/10.1002/9780470697870</dc:identifier_dbid>
    <dc:identifier_dbid>http://www.myilibrary.com?id=234220</dc:identifier_dbid>
    <dc:identifier_dbid>http://www.netlibrary.com/urlapi.asp?action=summary&amp;v=1&amp;bookid=323900</dc:identifier_dbid>
    <dc:identifier_dbid>http://catdir.loc.gov/catdir/toc/ecip0719/2007022434.html</dc:identifier_dbid>
</rdf:Description>
</rdf:RDF>

Open in new window

0
Comment
Question by:mmalik15
  • 4
6 Comments
 
LVL 18

Accepted Solution

by:
zc2 earned 250 total points
ID: 36523049
Please, give a try to the following script:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">

	<xsl:key name="ik" match="dc:identifier_isbn|dc:identifier_dbid" use="."/>

	<xsl:template match="rdf:Description">

		<xsl:for-each 
select="dc:identifier_isbn[string-length(normalize-space(.)) and generate-id(.) = generate-id(key('ik',.))]|dc:identifier_dbid[contains(.,'http://dx.doi.org') and generate-id(.) = generate-id(key('ik',.))]">
			<xsl:choose>
			   <xsl:when test="name() = 'dc:identifier_dbid'">
				   	<xsl:call-template name="after-slash">
				   		<xsl:with-param name="s" select="."/>
				   	</xsl:call-template>
			   </xsl:when>
			   <xsl:otherwise><xsl:value-of select="normalize-space(.)"/></xsl:otherwise>
			</xsl:choose>			
			<xsl:if test="position() != last()">; </xsl:if>
  		</xsl:for-each>
	</xsl:template>
	
	<xsl:template name="after-slash">
		<xsl:param name="s"/>
		<xsl:variable name="as" select="substring-after($s,'/')"/>
		<xsl:choose>
		   <xsl:when test="not(string-length($as))"><xsl:value-of select="$s"/></xsl:when>
		   <xsl:otherwise>
		   	<xsl:call-template name="after-slash">
		   		<xsl:with-param name="s" select="$as"/>
		   	</xsl:call-template>
		   
		   </xsl:otherwise>
		</xsl:choose>
	</xsl:template>	
	
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Assisted Solution

by:Geert Bormans
Geert Bormans earned 250 total points
ID: 36523104
The tricky bit is getting the part after the last '/' for which you need recursion
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:dc="http://purl.org/dc/elements/1.1/"
     exclude-result-prefixes="rdf dc"
    version="1.0">
    <xsl:template name="get-file-part">
        <xsl:param name="str"/>
        <xsl:choose>
            <xsl:when test="contains($str, '/')">
                <xsl:call-template name="get-file-part">
                    <xsl:with-param name="str" select="substring-after($str, '/')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$str"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template match="rdf:Description">
        <xsl:element name="misbn">
            <xsl:apply-templates select="dc:identifier_isbn[normalize-space(.)] | dc:identifier_dbid[contains(., 'dx.doi.org')][1]"/>
        </xsl:element>
    </xsl:template>
    
    <xsl:template match="dc:identifier_isbn">
        <xsl:if test="not(position() =  1)">
            <xsl:text>; </xsl:text>
        </xsl:if>
        <xsl:value-of select="."/>
    </xsl:template>

    <xsl:template match="dc:identifier_dbid">
        <xsl:if test="not(position() =  1)">
            <xsl:text>; </xsl:text>
        </xsl:if>
        <xsl:call-template name="get-file-part">
            <xsl:with-param name="str" select="."/>
        </xsl:call-template>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 36523196
I see that zc2 posted as well, solutions are almost equivalent, but zc2's solution provides unique nodes,
something you did not ask for, but I assume can be handy

other notable difference

- the choose construct in zc2's code is replaced by an apply templates, so the sector happens in the template matches.
Letting the template matching mechanism deal with choices is considered an XSLT best practice
- that also solves the issue you could run into with this <xsl:when test="name() = 'dc:identifier_dbid'">
if you prefer to keep the choose construct this would be better <xsl:when test="self::dc:identifier_dbid"> for various reasons
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Closing Comment

by:mmalik15
ID: 36523431
Excellent guys
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 36523443
Here is an alternative for my stylesheet, still having the matching doing its work after apply-templates,
but returning unique nodes only
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:dc="http://purl.org/dc/elements/1.1/"
     exclude-result-prefixes="rdf dc"
    version="1.0">
    
    <xsl:key name="unique" match="dc:identifier_isbn[normalize-space(.)] | dc:identifier_dbid[contains(., 'dx.doi.org')][not(preceding-sibling::dc:identifier_dbid[contains(., 'dx.doi.org')])]" use="normalize-space(.)"/>
    
    <xsl:template name="get-file-part">
        <xsl:param name="str"/>
        <xsl:choose>
            <xsl:when test="contains($str, '/')">
                <xsl:call-template name="get-file-part">
                    <xsl:with-param name="str" select="substring-after($str, '/')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="normalize-space($str)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template match="rdf:Description">
        <xsl:element name="misbn">
            <xsl:apply-templates select="*[generate-id() = generate-id(key('unique', normalize-space(.))[1])]"/>
        </xsl:element>
    </xsl:template>
    
    <xsl:template match="dc:identifier_isbn">
        <xsl:if test="not(position() =  1)">
            <xsl:text>; </xsl:text>
        </xsl:if>
        <xsl:value-of select="normalize-space(.)"/>
    </xsl:template>

    <xsl:template match="dc:identifier_dbid">
        <xsl:if test="not(position() =  1)">
            <xsl:text>; </xsl:text>
        </xsl:if>
        <xsl:call-template name="get-file-part">
            <xsl:with-param name="str" select="."/>
        </xsl:call-template>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 36523445
welcome
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Re-position the objects 7 99
Direct Mail software 4 46
fountain pens in usa 6 41
Problem to picture file 20 36
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
Whether you believe the “gig economy,” as it has been dubbed, is the next big economic paradigm shift (https://www.theguardian.com/commentisfree/2015/jul/26/will-we-get-by-gig-economy) or an overstated trend (http://www.wsj.com/articles/proof-of-a-g…
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now