Comment récupérer les attributs des frères et sœurs précédents dans XSLT


b00kgrrl

J'essaie de transformer un horrible XML avec un formatage riche en texte intégré en HTML. J'ai trouvé un moyen d'identifier le début d'une liste à puces, en fonction d'un attribut dans un nœud frère précédent, mais je ne peux pas comprendre comment mettre fin à la liste à puces. Le problème est que les attributs de chaque bloc de texte sont définis soit dans un nœud frère précédent, soit dans le premier paragraphe de la série.

J'ai le XML suivant:

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <item>
        <richtext>
            <pardef/>
            <par def='20'><run>This is the first </run><run>paragraph of the preamble.</run></par>
            <par><run>This is the second paragraph of the </run><run>preamble.</run></par>
            <pardef list='bullet'/>
            <par def='21'><run>This is the </run><run>first bullet.</run></par>
            <par><run>This is the second </run><run>bullet.</run></par>
            <par def='20'><run>This is the first </run><run>paragraph of the conclusion.</run></par>
            <par><run>This is the second paragraph of the </run><run>conclusion.</run></par>
        </richtext>
    </item>
</document>

Je veux la sortie suivante:

<p>This is the first paragraph of the preamble.</p>
<p>This is the second paragraph of the preamble.</p>
<ul>
    <li>This is the first bullet.</li>
    <li>This is the second bullet.</li>
</ul>
<p>This is the first paragraph of the conclusion.</p>
<p>This is the second paragraph of the conclusion.</p>

J'ai le XSLT suivant:

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

    <xsl:key name="key-for-par" match="document/item/richtext/par" use="generate-id(preceding-sibling::pardef[1])"/>
    <xsl:output indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates select="document/item/richtext/pardef" />
    </xsl:template>

    <xsl:template match="pardef[@list = 'bullet']">
        <ul>
            <xsl:for-each select="key('key-for-par', generate-id(.))">
                <li>
                    <xsl:value-of select="run" separator=""/>
                </li>
            </xsl:for-each>
        </ul>
    </xsl:template>

    <xsl:template match="pardef[not(@list)]">
            <xsl:for-each select="key('key-for-par', generate-id(.))">
                <p>
                    <xsl:value-of select="run" separator=""/>
                </p>
            </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
Jayvee

Selon les commentaires, en supposant que def = 21 est le début d'une liste à puces, nous pouvons ignorer 'pardef' et en utilisant 'par' dans un choix de construction, nous pouvons déterminer quand écrire ul, li, p et leurs balises de fermeture correspondantes. J'ai essayé ceci sur l'échantillon et même sur certaines variations de celui-ci et fonctionne bien:

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

    <xsl:template match="/">
        <xsl:apply-templates select="document/item/richtext/par" />
    </xsl:template>

    <xsl:template match="par">
    <xsl:if test="@def and preceding-sibling::par[@def][1][@def='21']"><xsl:text disable-output-escaping="yes">&lt;/ul&gt;</xsl:text></xsl:if>

    <xsl:choose>

        <xsl:when test="@def=21 or (not(@def) and preceding-sibling::par[@def][1][@def='21'])">
            <xsl:if test="@def=21"><xsl:text disable-output-escaping="yes">&lt;ul&gt;</xsl:text></xsl:if>
            <li>
                <xsl:for-each select="run">
                    <xsl:value-of select="text()" separator=""/>
                </xsl:for-each>
            </li>   
        </xsl:when>

        <xsl:when test="not(@def=21)">
            <p>
                <xsl:for-each select="run">
                    <xsl:value-of select="text()" separator=""/>
                </xsl:for-each>
            </p>    
        </xsl:when>     

    </xsl:choose>   

    </xsl:template>
</xsl:stylesheet>

Articles connexes


Comment imprimer les frères et sœurs précédents dans xpath

shorttriptomars J'essaie d'obtenir les frères et sœurs précédents d'un élément en utilisant xpath. Je recherche 2 frères et sœurs : sibling_two = driver.find_elements_by_xpath("//span[contains(@class, 'tag')]/preceding-sibling::a[2]") sibling_one = driver.find

XSLT - analyse des frères et sœurs suivants

Sanjay J'ai un xml comme suit, <doc> <section> <p id="main">main 1</p> <p id="main">main 2</p> <p id="para1">para1 1</p> <p id="main"> <p>para1 sub1</p> <p>para1 sub2</p> </p> <p id="m