For the Paragraph without header part images are n

2019-09-13 23:50发布

问题:

I'm having the two header files (h1, h2), I had write the image information using the below XSL:

My Input XSL:

<xsl:template match="Body">
        <xsl:for-each-group select="*" group-starting-with="h1">
           <xsl:if test="not(self::p/img)">
             <xsl:variable name="image" select="preceding-sibling::*[1][self::p/img]" />
             <topic>
                <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
                <title>
                   <xsl:apply-templates select="node()"/>
                </title>
                <xsl:for-each-group select="current-group() except ." group-starting-with="h2">
                   <xsl:choose>
                      <xsl:when test="self::h2">
                         <topic>
                            <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
                            <title>
                               <xsl:apply-templates select="node()"/>
                            </title>
                            <body><xsl:apply-templates select="current-group()[not(self::p/img)] except ."/></body>
                         </topic>
                      </xsl:when>
                      <xsl:otherwise>
                         <body><xsl:apply-templates select="$image|current-group()[not(self::p/img)]"/></body>
                      </xsl:otherwise>
                   </xsl:choose>
                </xsl:for-each-group>
                </topic>
             </xsl:if>
          </xsl:for-each-group>
       </xsl:template>

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

       <xsl:template match="img">
      <xsl:element name="image">
            <xsl:if test="@src">
               <xsl:attribute name="href"><xsl:value-of select="@src"/></xsl:attribute>
            </xsl:if>
       </xsl:element>
   </xsl:template>

My first input XML is(the image is not coming for this type):

<Body>
<p><img src="https://tneb.com"/></p>
<h1>Taking</h1>
<h2>Blood Pressure?</h2>
<p>second.</p>
</Body>

My second XML file:(Its generating image correctly)

<Body>
<p><img src="https://tneb.com"/></p>
<h1>Taking</h1>
<p>first</p>
<h2>Blood Pressure?</h2>
<p>second.</p>
</Body>

Generated output for first XML:

<topic id="topic_1">
   <title>Taking</title>
   <topic id="topic_2">
      <title>Blood Pressure?</title>
      <body>
         <p>second.</p>
      </body>
   </topic>
</topic>

Expected output would be:

<topic id="topic_1">
   <title>Taking</title>
<body>
  <p>
     <image href="https://tneb.com"/>
  </p>
</body>
   <topic id="topic_2">
      <title>Blood Pressure?</title>
      <body>
         <p>second.</p>
      </body>
   </topic>
</topic>

I have to create XSL for both type of inputs, Whether it having paragraph or not with the tag. Please suggest the coding for this.

Thanks in advance

回答1:

I think you need to add some logic to the check of self:h2 so that if it occurs in the first position (i.e. it has not p tags before it), then output the image there first

<xsl:when test="self::h2">
   <xsl:if test="position() = 1">
      <body><xsl:apply-templates select="$image"/></body>
   </xsl:if>

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="Body">
        <xsl:for-each-group select="*" group-starting-with="h1">
           <xsl:if test="not(self::p/img)">
             <xsl:variable name="image" select="preceding-sibling::*[1][self::p/img]" />
             <topic>
                <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
                <title>
                   <xsl:apply-templates select="node()"/>
                </title>
                <xsl:for-each-group select="current-group() except ." group-starting-with="h2">
                   <xsl:choose>
                      <xsl:when test="self::h2">
                        <xsl:if test="position() = 1">
                            <body><xsl:apply-templates select="$image"/></body>
                        </xsl:if>
                         <topic>
                            <xsl:attribute name="id">topic_<xsl:number count="h1 | h2"/></xsl:attribute>
                            <title>
                               <xsl:apply-templates select="node()"/>
                            </title>
                            <body><xsl:apply-templates select="current-group()[not(self::p/img)] except ."/></body>
                         </topic>
                      </xsl:when>
                      <xsl:otherwise>
                         <body><xsl:apply-templates select="$image|current-group()[not(self::p/img)]"/></body>
                      </xsl:otherwise>
                   </xsl:choose>
                </xsl:for-each-group>
                </topic>
             </xsl:if>
          </xsl:for-each-group>
       </xsl:template>

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

       <xsl:template match="img">
      <xsl:element name="image">
            <xsl:if test="@src">
               <xsl:attribute name="href"><xsl:value-of select="@src"/></xsl:attribute>
            </xsl:if>
       </xsl:element>
   </xsl:template>
</xsl:stylesheet>