Я хотел бы понять метод двухпроходной или многоэтапной обработки и уметь применять его в моем сценарии ниже.
Я все еще нахожусь на своих тренировочных колесах XSLT - большая часть контента здесь была собрана с помощью коллег или из онлайн-источников и модифицирована в соответствии с требованиями. Пожалуйста, простите меня, если что-то непонятно или мое понимание некорректно (любые предложения по улучшению рабочих частей тоже приветствуются)
Приведенный ниже XML-код представляет собой модифицированный образец моего входного xml. Ниже показаны одна запись и интересующие узлы (плюс немного пустяков для контекста).
<root><nNumber id="N472131">
<symbols>
<symbol href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/IP68_def.ai"/>
<symbol href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Bin@id
def.ai"/>
<symbol href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/CE0197_def.ai"/>
<symbol href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Recycle_def.ai"/>
<symbol href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Humidity0-90_def.ai"/>
<symbol href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Temp-10-55_def.ai"/>
</symbols>
</nNumber></root>
Мой XSLT фильтрует через предоставленный параметр в @id и выполняет незначительную перестановку @id
-> <id></id>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:param name="search"></xsl:param>
<!-- Identity transform - copies all elements and attributes. -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Filter nNumber nodes by ID. -->
<xsl:template match="nNumber">
<xsl:if test="@id=$search">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- Convert the ID value from an attribute to an element under the nNumber node. -->
<xsl:template match="@id">
<xsl:element name="{local-name(.)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:include href="ApplyOrder.xsl"/>
Последняя строка <xsl:include>
запускает серию совпадений с тегами символов, чтобы применить предопределенное значение порядка (пример ниже).
<xsl:template match="symbol[@href='file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/CE0197_def.ai']" >
<xsl:copy>
<xsl:attribute name="order">111</xsl:attribute><xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
Последний этап головоломки - упорядочить элементы символа по их значению @order (пример ниже). Я на собственном горьком опыте понял, что нельзя применить значение и отсортировать применяемое значение за одну операцию.
<symbol order="111" href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/CE0197_def.ai"/>
<symbol order="145" href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/IP68_def.ai"/>
<symbol order="171" href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Humidity0-90_def.ai"/>
<symbol order="172" href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Temp-10-55_def.ai"/>
<symbol order="181" href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Bin_2_def.ai"/>
<symbol order="191" href="file:///U:/Labelling/Labels/Common Symbols/symbols with definitions/Recycle_def.ai"/>
Итак, ниже моя попытка безупречно впихнуть пример многофазной обработки Майкла Кея в мой текущий сценарий.
У меня такое чувство, что я упускаю здесь что-то очень важное и фундаментальное - но я совершенно не понимаю, что это такое ...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:param name="search"></xsl:param>
<!-- Identity transform - copies all elements and attributes. -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="phase-1"/>
</xsl:copy>
</xsl:template>
<!-- Filter nNumber nodes by ID. -->
<xsl:template match="nNumber">
<xsl:if test="@id=$search">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="phase-1"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- Convert the ID value from an attribute to an element under the nNumber node. -->
<xsl:template match="@id">
<xsl:element name="{local-name(.)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:include href="ApplyOrder.xsl"/>
<xsl:template match="/">
<xsl:variable name="phase-1-result">
<xsl:apply-templates select="/" mode="phase-1"/>
</xsl:variable>
<xsl:apply-templates select="$phase-1-result" mode="phase-2"/>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*" mode="phase-2">
<xsl:sort select="."/>
</xsl:apply-templates>
<xsl:apply-templates select="node()" mode="phase-2">
<xsl:sort select="@order" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
The result of the transform gives something altogether different (tags are absent, text is not from the relevant node etc..). I am happy to publish a sample if anyone thinks it will help (I'm conscious that I'm already taking up enough screen real estate)
NB. Этот рабочий процесс предназначен для публикации XML с помощью InDesign. Однако преобразование будет выполнено в Oxygen v14.