xslt php ilk kardeşini ve onun tüm alt düğümleri seçmek

2 Cevap php

Nasıl bir tüm alt düğümler ile bir xml düğüm ilk kardeş seçin ve üzerine bazı dönüşümler geçerlidir? Şimdiye kadar sadece ilk ve tek kardeş ilk kardeşini (hiçbir alt düğümler) veya xml düğüm şu şeyi ya seçilmiş başardı.

Bunun gibi xhtmli var ki:

<div class="chapter">Chapter <span class="number">1.1</span> Lorum ipsum</div>
<h2 class="article">Article <span class="number">1.</span> Lorum ipsum</h2>
<p>Lorum ipsum</p>

Ve biz peşinde sonuç böyle xml olur:

<chapter>
  <heading>
    <label>Chapter</chapter>
    <number>1.1</number>
    <title>Lorum ipsum</title>
  </heading>
  <article>
    <heading>
      <label>Article</chapter>
      <number>1.</number>
      <title>Lorum ipsum</title>
    </heading>
    <par>Lorum ipsum</par>
  </article>
</chapter>

Benim tahminim ben etiket ve başlık etiketleri sağ olsun bazı regex büyü yapmak için ihtiyaç olduğunu, ancak bu aynı zamanda düz xslt kullanarak yapılmış olabilir, bu harika olurdu.

2 Cevap

Bu XSLT 1.0 dönüşüm:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="xhtml"
>
  <xsl:output encoding="utf-8" />

  <!-- the identity template (copies all nodes verbatim, unless
       more specific templates implement different behavior) -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

  <!-- start by applying templates to all chapter divs -->
  <xsl:template match="xhtml:html">
    <text>
      <xsl:apply-templates select="xhtml:body/xhtml:div[@class='chapter']" />
    </text>
  </xsl:template>

  <!-- chapter div: generate heading, apply templates to adjacent h2 -->
  <xsl:template match="xhtml:div[@class='chapter']">
    <chapter>
      <xsl:apply-templates select="." mode="heading" />
      <!-- ... where the first preceding chapter div has the same ID -->
      <xsl:apply-templates select="
        following-sibling::xhtml:h2[
          generate-id(preceding-sibling::xhtml:div[@class='chapter'][1])
          =
          generate-id(current())
        ]
      "/>
    </chapter>
  </xsl:template>

  <!-- h2: generate heading, apply templates to adjacent paras -->
  <xsl:template match="xhtml:h2[@class='article']">
    <article>
      <xsl:apply-templates select="." mode="heading" />
      <xsl:apply-templates select="
        following-sibling::xhtml:p[
          generate-id(preceding-sibling::xhtml:h2[@class='article'][1])
          =
          generate-id(current())
        ]
      "/>
    </article>
  </xsl:template>

  <!-- headings follow the same scheme, so we can use a unified template -->
  <xsl:template match="xhtml:div | xhtml:h2" mode="heading">
    <heading>
      <label>
        <xsl:value-of select="normalize-space(text()[1])" />
      </label>
      <number>
        <xsl:value-of select="normalize-space(xhtml:span[@class='number'])" />
      </number>
      <title>
        <xsl:value-of select="normalize-space(text()[2])" />
      </title>
    </heading>
  </xsl:template>

  <xsl:template match="xhtml:p">
    <par>
      <xsl:apply-templates select="node()" />
    </par>
  </xsl:template>

</xsl:stylesheet>

uygulandığında

<html xmlns="http://www.w3.org/1999/xhtml">
  <body>
    <div class="chapter">Chapter <span class="number">1.1</span> Lorum ipsum</div>
    <h2 class="article">Article <span class="number">1.</span> Lorum ipsum</h2>
    <p>Lorum ipsum A</p>
    <p>Lorum ipsum B</p>
    <h2 class="article">Article <span class="number">2.</span> Lorum ipsum</h2>
    <p>Lorum ipsum D</p>
    <h2 class="article">Article <span class="number">3.</span> Lorum ipsum</h2>
    <p>Lorum ipsum E</p>
    <p>Lorum ipsum F</p>
    <div class="chapter">Chapter <span class="number">2.1</span> Lorum ipsum</div>
    <h2 class="article">Article <span class="number">1.</span> Lorum ipsum</h2>
    <p>Lorum ipsum G</p>
  </body>
</html>

verimleri:

<text>
  <chapter>
    <heading>
      <label>Chapter</label>
      <number>1.1</number>
      <title>Lorum ipsum</title>
    </heading>
    <article>
      <heading>
        <label>Article</label>
        <number>1.</number>
        <title>Lorum ipsum</title>
      </heading>
      <par>Lorum ipsum A</par>
      <par>Lorum ipsum B</par>
    </article>
    <article>
      <heading>
        <label>Article</label>
        <number>2.</number>
        <title>Lorum ipsum</title>
      </heading>
      <par>Lorum ipsum D</par>
    </article>
    <article>
      <heading>
        <label>Article</label>
        <number>3.</number>
        <title>Lorum ipsum</title>
      </heading>
      <par>Lorum ipsum E</par>
      <par>Lorum ipsum F</par>
    </article>
  </chapter>
  <chapter>
    <heading>
      <label>Chapter</label>
      <number>2.1</number>
      <title>Lorum ipsum</title>
    </heading>
    <article>
      <heading>
        <label>Article</label>
        <number>1.</number>
        <title>Lorum ipsum</title>
      </heading>
      <par>Lorum ipsum G</par>
    </article>
  </chapter>
</text>

Bu stil istenilen çıktıyı oluşturur:

<xsl:template match="html:div[@class='chapter']" mode="chapter">
    <xsl:element name="{@class}">
        <heading>
            <xsl:apply-templates mode="chapter" />
        </heading>
        <xsl:apply-templates select="following-sibling::html:h2[generate-id(preceding-sibling::html:div[@class='chapter'][1])=generate-id(current())]" mode="chapter" />
    </xsl:element>
</xsl:template>

<!--template for h2 in "chapter" mode, creates article content for the chapter-->
<xsl:template match="html:h2[@class='article']" mode="chapter">
    <xsl:element name="{@class}">
        <heading>
            <xsl:apply-templates mode="chapter"/>
        </heading>
        <xsl:apply-templates select="following-sibling::html:p[generate-id(preceding-sibling::html:h2[@class='article'][1])=generate-id(current())]" mode="chapter" />
    </xsl:element>
</xsl:template>

<xsl:template match="text()[following-sibling::html:span[@class='number']]" mode="chapter">
    <label><xsl:value-of select="normalize-space()"/></label>
</xsl:template>

<!--Generate an (number) element using the class attribute as the name of the element-->
<xsl:template match="html:span[@class='number']" mode="chapter">
    <xsl:element name="{@class}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

<!--title elements created for text nodes before the -->
<xsl:template match="text()[preceding-sibling::html:span[@class='number']]" mode="chapter">
    <title><xsl:value-of select="normalize-space()"/></title>
</xsl:template>

<!--Template in "chapter" mode, creates a par element inside the article-->
<xsl:template match="html:p" mode="chapter">
    <para><xsl:value-of select="normalize-space()"/></para>
</xsl:template>

<!--prevent text from bleeding through in output-->
<xsl:template match="text()" mode="chapter"/>

Tomalak 'in örnek giriş XML kullanarak üretir:

<?xml version="1.0" encoding="UTF-8"?>
<book>
    <chapter>
        <heading>
            <label>Chapter</label>
            <number>1.1</number>
            <title>Lorum ipsum</title>
        </heading>
        <article>
            <heading>
                <label>Article</label>
                <number>1.</number>
                <title>Lorum ipsum</title>
            </heading>
            <para>Lorum ipsum A</para>
            <para>Lorum ipsum B</para>
        </article>
        <article>
            <heading>
                <label>Article</label>
                <number>2.</number>
                <title>Lorum ipsum</title>
            </heading>
            <para>Lorum ipsum D</para>
        </article>
        <article>
            <heading>
                <label>Article</label>
                <number>3.</number>
                <title>Lorum ipsum</title>
            </heading>
            <para>Lorum ipsum E</para>
            <para>Lorum ipsum F</para>
        </article>
    </chapter>
    <chapter>
        <heading>
            <label>Chapter</label>
            <number>2.1</number>
            <title>Lorum ipsum</title>
        </heading>
        <article>
            <heading>
                <label>Article</label>
                <number>1.</number>
                <title>Lorum ipsum</title>
            </heading>
            <para>Lorum ipsum G</para>
        </article>
    </chapter>
</book>