[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 369
  • Last Modified:

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

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
mmalik15
Asked:
mmalik15
  • 4
2 Solutions
 
zc2Commented:
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
 
Geert BormansCommented:
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
 
Geert BormansCommented:
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
mmalik15Author Commented:
Excellent guys
0
 
Geert BormansCommented:
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
 
Geert BormansCommented:
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.

  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now