Home > Software design >  Add parent node to a specific element xslt
Add parent node to a specific element xslt

Time:04-09

I would like to select Parent node without Child node.

Example:

<root>
    <p>some text</p>
    <ol>
      <li>
         <a href="http://cowherd.com" rel="nofollow">http://cowherd.com</a>
      </li>
    </ol>
    <p> <a href="http://cowherd.com" rel="nofollow">http://cowherd.com</a> </p>
    <a href="http://cowherd.com" rel="nofollow">http://cowherd.com</a>
</root>    

Desired Output: I want to add a parent

tag to those tags which don't have any parent except .

<root>
    <p>some text</p>
    <ol>
      <li>
         <a href="http://cowherd.com" rel="nofollow">http://cowherd.com</a>
      </li>
    </ol>
    <p> <a href="http://cowherd.com" rel="nofollow">http://cowherd.com</a> </p>
    <p> <a href="http://cowherd.com" rel="nofollow">http://cowherd.com</a> <p>
</root> 

I tried thi but it doesn't work. It adds the

tag around all tags.

 <xsl:template match="a">
  <xsl:if test="parent::*">
        <p><a>
            <!-- do not forget to copy possible other attributes -->
            <xsl:apply-templates select="@* | node()"/>
        </a></p>
</xsl:if>
    </xsl:template>

CodePudding user response:

I want to add a parent <p> tag to those <a> tags which don't have any parent except <root>.

I believe that boils down to:

XSLT 3.0

<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="/root/a">
    <p>
        <xsl:copy-of select="."/>
    </p>
</xsl:template>

</xsl:stylesheet>

CodePudding user response:

Here's a was this could be done :

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="a[not(parent::p)]">
    <p>
      <xsl:copy-of select="."/>
    </p>
  </xsl:template>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

See it working here : https://xsltfiddle.liberty-development.net/93F8dVt

  • Related