Add header and footer if they do not exist with XSLT

How can I force XSLT to wrap XML input in the parent node only if it does not already exist?

For example, if my input is:

<Project>...</Project>

I want to wrap it with a prefix and suffix:

<?xml version "1.0" encoding="utf-8">
<Site>
  <Project>...</Project>
</Site>

If, however, <Project> is not the root of the input node, I would like the input to remain unchanged.

Thanks in advance!

+3
source share
3 answers

This style sheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/Project">
        <Site>
            <xsl:call-template name="identity"/>
        </Site>
    </xsl:template>
</xsl:stylesheet>

Input 1:

<Project>...</Project>

Output 1:

<Site>
    <Project>...</Project>
</Site>

Input 2:

<Root>
    <Project>...</Project>
</Root>

Output 2:

<Root>
    <Project>...</Project>
</Root>

Note . Identity transformation. Pattern matching

+4
source

This conversion is :

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

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

 <xsl:template match="*[not(self::site)]/Project">
  <site>
    <xsl:call-template name="identity"/>
  </site>
 </xsl:template>
</xsl:stylesheet>

<Project> , <site>.

XML-:

<t>
  <Project>x</Project>
    <site>
      <Project>y</Project>
    </site>
</t>

, :

<t>
   <site>
      <Project>x</Project>
   </site>
   <site>
      <Project>y</Project>
   </site>
</t>
+1

If you add only the prefix and suffix, you can look for other Unix options, such as grep, that can make this a lot easier. If you want to do this in XSL then you use xsl: when

<xsl:template match="/">
         <xsl:choose>       <!-- If Node Period exists add the text -->         <xsl:when test="Period">
                        <xsl:text><Site></xsl:text>
                        <xsl:text>&#xa;</xsl:text>
                        <xsl:text><Site></xsl:text>
            </xsl:when>     </xsl:choose>   <xsl:apply-templates select="Notification"/> </xsl:template>
0
source

Source: https://habr.com/ru/post/1757085/


All Articles