somedev
somedev

Reputation: 1053

Dealing with url tags within a node

Input:

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="NOIA" xsi:noNamespaceSchemaLocation="sample.xsd">
<id>X17A</id>
<companyName>Foo Bars</companyName>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis tincidunt turpis id metus porttitor convallis. Duis ullamcorper magna a est suscipit eget blandit magna ullamcorper. Vivamus sit amet auctor elit.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis tincidunt turpis id metus porttitor convallis. Duis ullamcorper magna a est suscipit eget blandit magna ullamcorper. Vivamus sit <url>http://www.google.com/</url> amet auctor elit.</p>
</document>

Desired Output:

<html>
<body>
<h1>Foo Bars Company</h1>
<div><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis tincidunt turpis id metus porttitor convallis. Duis ullamcorper magna a est suscipit eget blandit magna ullamcorper. Vivamus sit amet auctor elit.</p></div>
<div><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis tincidunt turpis id metus porttitor convallis. Duis ullamcorper magna a est suscipit eget blandit magna ullamcorper. Vivamus sit <a href="http://www.google.com/">http://www.google.com/</a> amet auctor elit.</p></div>
</body>
</html>

Here is as far as I got with the sheet:

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0">

<xsl:output method="html" indent="yes" version="4.0"/>

<xsl:template match="/">
<html>
  <body>
    <xsl:apply-templates/>
  </body>
</html>
</xsl:template>

<xsl:template match="id"></xsl:template>

<xsl:template match="companyName">
<h1><xsl:value-of select="."/></h1>
</xsl:template>

<xsl:template match="url">
<a href="#test"><xsl:value-of select="."/></a>
</xsl:template>

<xsl:template match="p">
<div><p><xsl:value-of select="."/></p></div>
</xsl:template>

</xsl:stylesheet>

I can't figure out how to put the value in the href=""

Also, this doesn't end up with an href, I'm just getting the text in a p.

Upvotes: 0

Views: 213

Answers (1)

ABach
ABach

Reputation: 3738

When this XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
  <xsl:output omit-xml-declaration="no" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="url">
    <a href="{.}">
      <xsl:apply-templates />
    </a>
  </xsl:template>

  <xsl:template match="/*">
    <html>
      <body>
        <xsl:apply-templates select="*" />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="id" />

  <xsl:template match="companyName">
    <h1>
      <xsl:value-of select="concat(., ' Company')" />
    </h1>
  </xsl:template>

  <xsl:template match="p">
    <div>
      <p>
        <xsl:apply-templates />
      </p>
    </div>
  </xsl:template>
</xsl:stylesheet>

...is applied to the originally provided XML:

<?xml version="1.0" encoding="utf-8"?>
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
type="NOIA" xsi:noNamespaceSchemaLocation="sample.xsd">
  <id>X17A</id>
  <companyName>Foo Bars</companyName>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis
  tincidunt turpis id metus porttitor convallis. Duis ullamcorper
  magna a est suscipit eget blandit magna ullamcorper. Vivamus sit
  amet auctor elit.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis
  tincidunt turpis id metus porttitor convallis. Duis ullamcorper
  magna a est suscipit eget blandit magna ullamcorper. Vivamus sit 
  <url>http://www.google.com/</url>amet auctor elit.</p>
</document>

...the desired result is produced:

<html>
  <body>
    <h1>Foo Bars Company</h1>
    <div>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      Duis tincidunt turpis id metus porttitor convallis. Duis
      ullamcorper magna a est suscipit eget blandit magna
      ullamcorper. Vivamus sit amet auctor elit.</p>
    </div>
    <div>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      Duis tincidunt turpis id metus porttitor convallis. Duis
      ullamcorper magna a est suscipit eget blandit magna
      ullamcorper. Vivamus sit 
      <a href="http://www.google.com/">
      http://www.google.com/</a>amet auctor elit.</p>
    </div>
  </body>
</html>

Note that this solution will work with either XSLT 1.0 or XSLT 2.0.

Explanation:

  • The first template is The Identity Transform. It's purpose is to copy all nodes and attributes as-is from the source document to the result document.

  • The second template matches any <url> element found in the document. Upon finding a <url> element, a new <a> element is created, given an href attribute that matches the original value of the <url> element (via XSLT's AVT [Attribute Value Template] functionality), and given a value that matches that original <url> value.

Note that if elements other than <url> need to be replaced in this same manner, you can simply alter the match attribute of the second template as necessary. For example:

<xsl:template match="url|some-other-element|yetAnotherElement">
  • The third template matches any <id> element and, in place of that element, outputs nothing (which effectively deletes that element).

  • The fourth template matches any <companyName> element. In its place, a new <h1> element is created and given a value that is a concatenation of <companyName>'s value and " Company".

  • The fifth template matches any <p> element and wraps it in a <div> element.

Upvotes: 1

Related Questions