Я использую XSLT для преобразования XML-документов, содержащих сложную структуру данных, свободного текста и т. Д. В документ HTML. Документы, которые я обрабатываю, могут быть с конструктивными элементами или без них, и если существующие структурные теги могут быть вложены произвольно. Теги данных могут ссылаться на на любой тип товаров, поэтому я заранее не знаю содержание документа XML.Xsl Сохранение текстового порядка вывода
Документы выглядит
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="my.xsl"?>
<doc>
<elementStructure type="tag">
The following items are cars:
<Car id="12" type="data" value="Ferrari"> this is a sport car.
<structureLev2 type="tag">
<Model id="432" value="458" />
<Rim id="55" value="wheels of car" type="data">
<Tire id="234" value="front" type="data">
<Note id="33" value="special tire" type="data"/> size of front is less that rear.
<TypeTire id="44" value="radial tire" type="data"/>
</Tire>
</Rim>
</structureLev2>
</Car>
</elementStructure>
<elementStructure type="tag">
Other text
<Car id="22" type="data" value="Ford">
this is a family car.
<structureLev2 type="tag">
<Model id="872" value="Mondeo" />
<Rim id="45" value="wheels of car" type="data">
<Tire id="734" value="front" type="data">
<Note id="63" value="normal tire" type="data"/> spare tire could be replaced by run-flat.
<TypeTire id="84" value="tubeless tire" type="data"/>
</Tire>
</Rim>
</structureLev2>
</Car>
</elementStructure>
</doc>
Desiderata HTML документ должен выглядеть примерно так:
<section>
Some text....
<ul>
<li>Car - Ferrari (this is a sport car.)</li>
<li>Rim - wheels of the car:</li>
<ul>
<li>Tire - front Note: special tire (size of front is less than rear).</li>
<li>TypeTire - radial tire
</ul>
</ul>
</section>
На самом деле я не знаю, если это хорошее решение, но так как я не знаю, если мой xml содержит или не структурные теги, я использовал «переключатель» для выбора между двумя основными шаблонами.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:strip-space elements="*"/>
<xsl:template match="doc">
<html>
<body>
<xsl:choose>
<xsl:when test="//*[@type='tag']">
<xsl:call-template name="stuct" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="plain" />
</xsl:otherwise>
</xsl:choose>
</body>
</html>
</xsl:template>
<xsl:template match="doc/*[@type='tag']" name="stuct">
<h3>
<xsl:value-of select="text()"/>
</h3>
<xsl:apply-templates mode="str"/>
</xsl:template>
<xsl:template match="doc/*[@type='tag']" mode="str">
<ul>
<li>
<xsl:call-template name="dataElem"/>
<xsl:apply-templates mode="str"/>
</li>
</ul>
</xsl:template>
<xsl:template match="doc/*[@type='data']" name="dataElem">
<xsl:for-each select="descendant::node()[not(@type='tag')]">
<xsl:value-of select="name(.)"/>: <xsl:value-of select="@value" /> (<xsl:value-of select="text()"/>)<br/>
</xsl:for-each>
</xsl:template>
<xsl:template match="doc/*[@type='data']" name="plain">
<xsl:call-template name="dataElem" />
</xsl:template>
</xsl:stylesheet>
Среди всех проблем, которые я получил, начиная с самого кода :-) одна проблема, которая возникает о тексте. Я хочу, чтобы текст между тегами мог появляться только один раз, а после «проанализированного» элемента. Является ли это возможным?
Это именно то, что мне нужно! Отлично. Да, мой результат был неправильным. Я теряюсь с применением шаблонов. Благодаря! – user1732337