как отдельно извлечь дочерние элементы из вложенных тегов с помощью xslt - PullRequest
0 голосов
/ 22 февраля 2019

мой XML-код ввода:

<code>        <pre>
            <title>title of xml</title>
            <em>
            <h2> headings</h2>
            <title>write title here</title>
            <pre>
            <h1>heading h1</h1>
            
            <li>list here</li>
            

Фактический вывод:

            <div>
            <title>title of xml</title>
            <h2> headings</h2>
            <title>write title here</title>
            <h1>heading h1</h1>
            <li>list here</li>
            </div>

ожидаемый вывод:

             <div>
                <title>title of xml</title>
             </div>
             <div>
                <h2> headings</h2>
                <title>write title here</title>
              </div>
              <div>
                <h1>heading h1</h1>
              </div>
              <div>
                <li>list here</li>
               </div>

мой xsl-код:

        <xsl:template match="content/body//pre|em">
                  <xsl:choose>
                     <xsl:when test="pre">
                        <xsl:apply-templates />
                     </xsl:when>
                     <xsl:otherwise>
                        <div>
                           <xsl:apply-templates />
                        </div>
                     </xsl:otherwise>
                  </xsl:choose>
               </xsl:template>
            <xsl:template match="content/body/pre/em/pre">
                  <xsl:apply-templates select="./node()" />
            </xsl:template>

Мне нужно изменить теги pre и em на тег div и извлечь все эти div отдельно. Но в соответствии с моим кодом, я могу получить все дочерниеэлемент в одном теге div, который не соответствует моим ожиданиям. Пожалуйста, предоставьте некоторые предложения по этому вопросу.

Ответы [ 4 ]

0 голосов
/ 23 февраля 2019

Это проблема группировки .В XSLT 2.0 вы можете использовать это преобразование

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/">
        <xsl:for-each-group select="//*"
            group-starting-with="pre|em">
            <div>
                <xsl:apply-templates select="current-group()/(* except (em|pre))" />
            </div>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

И этот вход

<code><pre>
    <title>title of xml</title>
    <em>
        <h2> headings</h2>
        <title>write title here</title>
        <pre>
            <h1>heading h1</h1>
        
            <li>list here</li>
        

Результат

<div>
   <title>title of xml</title>
</div>
<div>
   <h2> headings</h2>
   <title>write title here</title>
</div>
<div>
   <h1>heading h1</h1>
</div>
<div>
   <li>list here</li>
</div>
0 голосов
/ 22 февраля 2019
<xsl:template match="*|@*">
    <xsl:copy>
        <xsl:apply-templates select="*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="title">
    <xsl:choose>
        <xsl:when test=" not(preceding::title)">
            <div>
                <title>
                    <xsl:value-of select="."/>
                </title>
            </div>
        </xsl:when>
        <xsl:when test="preceding-sibling::*[1][self::h2]">
            <div>
                <xsl:copy-of select="preceding-sibling::*[1][self::h2]"/>
                <title><xsl:value-of select="."/></title>
            </div>
        </xsl:when>
    </xsl:choose>
</xsl:template>

<xsl:template match="h1|li">
    <div>
        <xsl:copy-of select="."/>
    </div>
</xsl:template>

<xsl:template match="pre|em">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="h2"/>
0 голосов
/ 22 февраля 2019

Этого можно добиться, применяя шаблоны к целевым узлам

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

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

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

    <xsl:template match="/pre">
        <div>
            <xsl:apply-templates select="*[not(self::em)]"/>
        </div>
        <xsl:apply-templates select="em"/>
    </xsl:template>

    <xsl:template match="em">
        <div>
            <xsl:copy-of select="*[not(self::pre)]"/>
        </div>
        <xsl:apply-templates select="pre"/>
    </xsl:template>

    <xsl:template match="em/pre">
        <div>
            <xsl:apply-templates/>
        </div>
    </xsl:template>

</xsl:stylesheet>

Смотрите его в действии здесь .

0 голосов
/ 22 февраля 2019
<xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="h2"/>

    <xsl:template match="pre|em">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="title">
        <xsl:choose>
            <xsl:when test=" not(preceding::title)">
                <div>
                    <title>
                        <xsl:value-of select="."/>
                    </title>
                </div>
            </xsl:when>
            <xsl:when test="preceding-sibling::*[1][self::h2]">
                <div>
                    <xsl:copy-of select="preceding-sibling::*[1][self::h2]"/>
                    <title><xsl:value-of select="."/></title>
                </div>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="h1">
        <div>
            <h1><xsl:value-of select="."/></h1>
        </div>
    </xsl:template>

    <xsl:template match="li">
        <div>
            <li><xsl:value-of select="."/></li>
        </div>
    </xsl:template>
Try it.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...