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
353 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 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
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

How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
how many cores in note3? 5 103
Search all sub-folder 4 65
Windows 7 to Windows 10 and back. IE 9.0, 10.0, 11.0 10 84
Passing client data from form to server 5 54
If you want to move up through the ranks in your technology career, talent and hard work are the bare necessities. But they aren’t enough to make you stand out. Expanding your skills, actively promoting your accomplishments and using promotion st…
If you get continual lockouts after changing your Active Directory password, there are several possible reasons.  Two of the most common are using other devices to access your email and stored passwords in the credential manager of windows.
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

738 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