Nasıl güzel kaldırılan kaynak unsurları ile bir XSLT sonuç belgesini yazdırırım?

2 Cevap php

Ben (Açıkçası hiçbir ad alanları ile) bir HTML belgesine dönüşürken am birden fazla ad alanı elemanları ile bir kaynak XHTML belge var. Benim XSL şablonları ben sadece sonuç ağacından olmayan HTML-uyumlu öğeleri kaldırmak için XHTML ad elemanları maç. Bu elemanlar gitti Ancak, çıktı,, boşluk onları kalır-yani girinti için kullanılan, alakasız CR / LFS ve sekmeler hatları.

Örneğin, bu benim girişi ise:

<div id="container">
    <svg:svg>
        <svg:foreignObject>
            <img />
        </svg:foreignObject>
    </svg:svg>
</div>

Dönüşümü uygulandıktan sonra, bu çıkış olacaktır:

<div id="container">


            <img />


</div>

Benim desired çıkışı bu iken:

<div id="container">
    <img />
</div>

Bu TransforMiiX (Firefox yerel stil bağlama) ve libxslt (PHP ile stil sunucu tarafı bağlama) her ikisini de kullanarak olur, bu yüzden muhtemelen bazı XSL parametre seti almıyorum sonucu olduğunu biliyorum, ama ben {[oynuyor denedim (0)]}, xml:space="default|preserve", <xsl:strip-space elements="foo bar|*" />, tüm boşuna.

Ham XSL bunu yapmak için hiçbir yolu yoktur, ancak PHP bunu yapmak için bir yol olup olmadığını ben kabul edeceğiz böylece bu sunucu tarafı uygulanacaktır.

Ben HERHANGİ eleman çıkarmak eğer ben aynı sonucu elde beri bu ad sorunu olmadığını biliyoruz.

2 Cevap

Gördüğünüz beyaz boşluk kaynak belgeden olduğunu. XSLT varsayılan kurallar onlar boş olup olmadığını farketmez, metin düğümleri kopyalanamaz gerektiğini söylüyorlar. Varsayılan kuralı geçersiz kılmak için, şunlardır:

<xsl:template match="text()" />

Alternatif olarak: Herhangi bir <xsl:apply-templates /> (veya <xsl:apply-templates select="node()" />) Nokta ve açıkça size şablonları uygulamak istediğiniz which çocukları belirtin. Lütfen dönüşüm kısmen (bu durumda metin düğümleri için boş şablon karşı üretken olacaktır) kimlik şablona dayanan bu yöntem, gerekli olabilir.

Ben snippet'inizde Kelime yapacağını yolu içinde "önemsiz" beyaz boşluk işaretlenmiş var:

<div id="container">¶
····<svg:svg>¶
········<svg:foreignObject>¶
············<img />¶
········</svg:foreignObject>¶
····</svg:svg>¶
</div>

EDIT: Ayrıca kimlik şablonu bu gibi değiştirebilirsiniz:

<xsl:template match="node() | @*">
  <xsl:copy>
    <!-- select everything except blank text nodes -->
    <xsl:apply-templates select="
      node()[not(self::text())] | text()[normalize-space() != ''] | @*
    " />
  </xsl:copy>
</xsl:template>

Bu kaldırmak any boş-yalnızca metin düğümü (nitelik değerleri onlar metin düğümleri değil, bakir kalır). Olur <xsl:output indent="yes" /> sonucu güzel-yazdırmak için kullanın.

Eğer boşluk farklı işlemek için orijinal dönüşüm düzeltmek, ya da olduğu gibi-size dönüşümü tutmak ve çıkış güzelleştirmek için ikinci bir geçiş eklemek ya: İstediğiniz sonuca ulaşmak için iki yol vardır. Özgün dönüşüm karmaşık ise o zaman 2-pass yaklaşımı öneriyoruz. Size dönüşüm daha da karmaşık hale getirmek istemiyorum ya istenen sonuç alamadım nereye bazı köşe durumlarda edeceğiz oluşturun ve size daha özel durum işleme eklemek zorunda ve potansiyel çalışmak için kullanılan bir şey için hata ekleriz , vs ..

Sen normalize-text() ile bunları test ederek boşluk düğümleri görmezden gerekir. Burada ikinci bir geçiş gibi görünebilir nasıl. Eğer 1-geçiş yaklaşımı ile giderseniz, kod sanırım kabaca aynı olacaktır.

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

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

    <xsl:template match="text()">
        <xsl:if test="normalize-space(.) != ''">
            <xsl:value-of select="."/>
        </xsl:if>
    </xsl:template>

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

</xsl:stylesheet>