Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
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
Medium Priority
?
367 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
6 Comments
 
LVL 19

Accepted Solution

by:
zc2 earned 1000 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 1000 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

This story has been written with permission from the scammed victim, a valued client of mine – identity protected by request.
Digital marketing agencies have encountered both the opportunities and difficulties that emerge from working with a wide-ranging organizations.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
The Bounty Board allows you to request an article or video on any technical topic, or fulfill a bounty request to earn points. Watch this video to learn how to use the Bounty Board to get the content you want, earn points, and browse submitted bount…

636 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