1

我想了解的是两遍或多阶段处理的方法,并能够在下面的场景中应用它。

我仍在使用我的 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_2_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"/>

因此,下面是我尝试将 Michael Kay 的多阶段处理示例粗鲁地塞进我当前的场景中。

我觉得我在这里遗漏了一些非常重要和基本的东西——但我完全没有意识到它是什么......

<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>

转换的结果给出了完全不同的东西(标签不存在,文本不是来自相关节点等)。如果有人认为它会有所帮助,我很乐意发布一个样本(我意识到我已经占用了足够的屏幕空间)

注意:此工作流程适用于使用 InDesign 进行 XML 发布。但是,转换将在 Oxygen v14 中运行。

4

1 回答 1

3
<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()" mode="phase-1">
        <!-- ---------------------- ^^^^^^^^^^^^^^ -->
    </xsl:template>

    <!-- ... --->

    <xsl:template match="node()|@*" mode="phase-2">
        <!-- ---------------------- ^^^^^^^^^^^^^^ -->
    </xsl:template>
</xsl:stylesheet>

笔记

  • 您在您的模板中提到了模板模式,<xsl:apply-templates>但忘记在实际模板上声明它们。
  • 为什么要按属性按字典顺​​序排列属性?排序属性一开始没有任何意义。它们应该是元数据。不要费心订购它们,不要构建任何依赖于属性顺序的东西。
于 2013-10-15T05:19:12.223 回答