Отображать теги потомков как теги в XSLT - PullRequest
0 голосов
/ 28 апреля 2020

Я хочу отобразить некоторые конкретные теги потомков в виде тегов в выводе XSLT:

У меня есть xml, подобное следующему:

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type='text/xsl' href='item-jerd.xsl'?>
<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" article-type="research-article">
<front id="meta">
<article-meta id="art">
<contrib-group>
<affiliation id="affiliation1">Production Engineering,<institution-wrap><institution>Engineering and Technology</institution></institution-wrap><city>Dhanga</city><country country="IN">India</country></affiliation>
<affiliation id="affiliation2">Industrial and Production Engineering,<institution-wrap><institution>India University of Engineering and Technology</institution></institution-wrap><city>Dukka</city><country country="IN">India</country></affiliation>
<affiliation id="affiliation3">Industrial Systems Engineering,<institution-wrap><institution>University of Regina</institution></institution-wrap><city>Regina</city>, Saskatchewan,<country country="CA">Canada</country></affiliation>
</contrib-group>
<author-notes>
<corresp id="cor1">GBWIN is the owner and can be contacted at:<ext-link ext-link-type="email" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="mailto:bwin@gmail.com">bwin@gmail.com</ext-link></corresp>
</author-notes>
</article-meta>
</front>
<body/>
</article>

Я использовал приведенное ниже условие xslt :

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="/">
<html>
<head>
<title>HELP ME</title>
</head>
<body onkeyup="keyDown=0" onkeydown="keyDown=1">
<div class="content" id="main">
<xsl:call-template name="main"/>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="journalStylesheet/baseData" name="main">
<h1>Author info</h1>
<table  border="1" width="1200" bgcolor="#CCFFCC">      
<xsl:for-each select="//affiliation">
<tr>
<td width="5%">
<font class="head3">
<xsl:variable name="attr" select="./@id" />
<xsl:if test="$attr">                               
<a name="{$attr}">
<xsl:value-of select="$attr"/>
</a>                                
</xsl:if>
</font>
</td>
<td width="95%">
<font class="head3">
<xsl:value-of select="."/>
</font>
</td>
</tr>
</xsl:for-each>
</table>
<h2>Author Notes</h2>
<table  border="1" width="1200" bgcolor="#CCFFCC"> 
<xsl:for-each select="//author-notes/*"><tr>
<td width="40%" class="head3">Author-notes</td>
<td width="60%" class="head3">
<xsl:value-of select="."/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>

Я хочу вывод HTML аффилированных данных и тегов заметок автора, как показано ниже

Production Engineering,<institution-wrap><institution>Engineering and Technology</institution></institution-wrap><city>Dhanga</city><country country="IN">India</country><br />
Industrial and Production Engineering,<institution-wrap><institution>India University of Engineering and Technology</institution></institution-wrap><city>Dukka</city><country country="IN">India</country><br />
Industrial Systems Engineering,<institution-wrap><institution>University of Regina</institution></institution-wrap><city>Regina</city>, Saskatchewan,<country country="CA">Canada</country>

, но получаю вывод как

Технологии, инженерия и TechnologyDhangaIndia Промышленный и производственный инжиниринг, Индийский инженерно-технологический университетDukkaIndia Инженерия промышленных систем, Университет Реджина Реджина, Саскачеван, Канада Теги должны отображаться в html для вывода

1 Ответ

0 голосов
/ 28 апреля 2020

В XSLT-1.0 вы можете достичь этого с помощью (не всегда реализованного) атрибута disable-output-escaping="yes" xsl:value-of.
Поэтому примените следующие модификации:

  1. Измените вызывая шаблон для вызова под-шаблонов с модификатором mode и добавлением xsl:if для добавления окончательных тегов <br>:

    ...
    <td width="95%">
        <font class="head3">
            <xsl:apply-templates select="node()" mode="serialize" />
            <xsl:if test="position() != last()">
                <br />
            </xsl:if>
        </font>
    </td>
    ...
    
  2. Добавьте следующие шаблоны для обработки подэлементы в этом режиме:

    <!-- Remove leading and trailing spaces from each text() node -->
    <xsl:template match="text()" mode="serialize">
        <xsl:value-of select="normalize-space(.)" />
    </xsl:template>
    
    <!-- Skip all attributes in this mode because they are handled otherwise -->
    <xsl:template match="@*" mode="serialize" />
    
    <!-- Recreate all elements in this mode -->
    <xsl:template match="*" mode="serialize">
        <!-- ReCreate the current element tag -->
        <xsl:value-of disable-output-escaping="yes" select="concat('&lt;',name())" />
        <!-- Copy the attributes of the current element -->
        <xsl:if test="@*">
            <xsl:value-of select="' '" />
            <xsl:for-each select="@*">
                <xsl:value-of select="concat(name(),'=&quot;',.,'&quot;')" />
            </xsl:for-each>
        </xsl:if>
        <!-- Close the opening element -->
        <xsl:value-of disable-output-escaping="yes" select="'&gt;'" />
        <!-- Apply all sub-nodes -->
        <xsl:apply-templates select="node()|@*" mode="serialize" />
        <!-- ReCreate the closing element tag -->
        <xsl:value-of disable-output-escaping="yes" select="concat('&lt;/',name(),'&gt;')" />
    </xsl:template>
    

Часть его вывода:

...
<table border="1" width="1200" bgcolor="#CCFFCC">
  <tr>
    <td width="5%">
        <font class="head3">
            <a name="affiliation1">affiliation1</a>
        </font>
    </td>
    <td width="95%">
        <font class="head3">
            Production Engineering,
            <institution-wrap>
                <institution>Engineering and Technology</institution>
            </institution-wrap>
            <city>Dhanga</city>
            <country country="IN">India</country>
            <br>
        </font>
    </td>
</tr>
<tr>
    <td width="5%">
        <font class="head3">
            <a name="affiliation2">affiliation2</a>
        </font>
    </td>
    <td width="95%">
        <font class="head3">
                Industrial and Production Engineering,
                <institution-wrap>
                    <institution>India University of Engineering and Technology</institution>
                </institution-wrap>
                <city>Dukka</city>
                <country country="IN">India</country>
                <br>
            </font>
        </td>
    </tr>
    <tr>
        <td width="5%">
            <font class="head3">
                <a name="affiliation3">affiliation3</a>
            </font>
        </td>
        <td width="95%">
            <font class="head3">
                    Industrial Systems Engineering,
                    <institution-wrap>
                        <institution>University of Regina</institution>
                    </institution-wrap>
                    <city>Regina</city>
                    , Saskatchewan,<country country="CA">Canada</country>
            </font>
      </td>
  </tr>
</table>
...

, что близко к желаемому. Теги <br /> отображаются как теги <br> из-за метода вывода HTML.


Весь код XSLT-1.0, который включает в себя вышеуказанное улучшение, будет:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:output method="html" encoding="UTF-8"/>
    <xsl:template match="/">
        <html>
            <head>
                <title>HELP ME</title>
            </head>
            <body onkeyup="keyDown=0" onkeydown="keyDown=1">
                <div class="content" id="main">
                    <xsl:call-template name="main"/>
                </div>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="journalStylesheet/baseData" name="main">
        <h1>Author info</h1>
        <table  border="1" width="1200" bgcolor="#CCFFCC">      
            <xsl:for-each select="//affiliation">
                <tr>
                    <td width="5%">
                        <font class="head3">
                            <xsl:variable name="attr" select="./@id" />
                            <xsl:if test="$attr">                               
                                <a name="{$attr}">
                                    <xsl:value-of select="$attr"/>
                                </a>

                            </xsl:if>
                        </font>
                    </td>
                    <td width="95%">
                        <font class="head3">
                            <xsl:apply-templates select="node()" mode="serialize" />
                            <xsl:if test="position() != last()">
                                <br />
                            </xsl:if>
                        </font>
                    </td>
                </tr>
            </xsl:for-each>
        </table>
        <h2>Author Notes</h2>
        <table  border="1" width="1200" bgcolor="#CCFFCC"> 
            <xsl:for-each select="//author-notes/*"><tr>
                    <td width="40%" class="head3">Author-notes</td>
                    <td width="60%" class="head3">
                        <xsl:value-of select="."/>
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>

    <xsl:template match="text()" mode="serialize">
        <xsl:value-of select="normalize-space(.)" />
    </xsl:template>

    <!-- Skip all attributes in this mode because they are handled otherwise -->
    <xsl:template match="@*" mode="serialize" />

    <!-- Recreate all elements in this mode -->
    <xsl:template match="*" mode="serialize">
        <!-- ReCreate the current element tag -->
        <xsl:value-of disable-output-escaping="yes" select="concat('&lt;',name())" />
        <!-- Copy the attributes of the current element -->
        <xsl:if test="@*">
            <xsl:value-of select="' '" />
            <xsl:for-each select="@*">
                <xsl:value-of select="concat(name(),'=&quot;',.,'&quot;')" />
            </xsl:for-each>
        </xsl:if>
        <!-- Close the opening element -->
        <xsl:value-of disable-output-escaping="yes" select="'&gt;'" />
        <!-- Apply all sub-nodes -->
        <xsl:apply-templates select="node()|@*" mode="serialize" />
        <!-- ReCreate the closing element tag -->
        <xsl:value-of disable-output-escaping="yes" select="concat('&lt;/',name(),'&gt;')" />
    </xsl:template>

</xsl:stylesheet>

Вывод:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...