4.1.2.7  Mixed Content wrappen

Transformation-Patterns Mixed Content wrappen Sehr unangenehm ist sporadisch auftretender XML Mixed Content, z.B. zwischen Paras. Mit folgenden Templates lässt sich das handeln. Zuerst kann man den Mixed Content in einem vorhergehenden Schritt markieren und in einen künstlichen Para packen ...

<!-- wrap a p around PCDATA in li -->
    
<xsl:template match="text()[parent::li]">
  <p content="mixed">
    <xsl:value-of select="."/>
  </p>
</xsl:template>
Plain Text

... hier markiert mit @content="mixed" . Im folgenden Schritt werden dann die ursprünglichen Paras, die jetzt verschachtelt im künstlichen Para liegen wieder ausgepackt:

<xsl:variable name="inline-elements" select="('sub','sup','b','i','br','u')"/>

<xsl:template match="p[@content='mixed' and not(preceding-sibling::p[@content='mixed'])]">
  <xsl:variable name="first-p-id" select="(preceding-sibling::*[1]/generate-id(), 
                                                                   generate-id())[1]"/>
  <p>
    <xsl:copy-of select="preceding-sibling::*[name()=$inline-elements]"/>
      <xsl:apply-templates select="node()|following-sibling::*[(self::p[@content='mixed']
                           or name()=$inline-elements) and 
			   not(preceding-sibling::p[not(@content='mixed')][1]/
                           generate-id()!=$first-p-id)]" mode="unwrap"/>
   </p>
</xsl:template>
	
<xsl:template match="p[@content='mixed' and preceding-sibling::p[@content='mixed']]"/>
	
<xsl:template match="p" mode="unwrap">
  <xsl:apply-templates/>
</xsl:template>
	
<xsl:template match="*[not(self::p)]" mode="unwrap">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>
	
<xsl:template match="li[p[@content='mixed']]/*[name()=$inline-elements]"/>
Plain Text