我有父子标记结构,需要迭代父标记的子标记,并以新格式设置值。
父标签和子标签都可以重复属性。
我们需要检查子/中是否存在值/标记,然后将其从父标记中取出。
以下是示例xml
<?xml version="1.0" encoding="UTF-8"?>
<item>
<perishable-indicator >N</perishable-indicator>
<product-shelf-security-type >ST - SMALL TOY</product-shelf-security-type>
<before-date>2012-05-30</before-date>
<partnumber>2</partnumber>
<season>BASIC SEASON</season>
<variant>
<partnumber>4</partnumber>
<season>BASIC SEASON</season>
<division-code>055</division-code>
<department-code>013</department-code>
<class-code>089</class-code>
</variant>
</item>
以下是用于迭代父级和子级的示例XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="item">
<Product>
<xsl:variable name="productperishable" select="perishable-indicator"/>
<xsl:variable name="productsecurity-type" select="product-shelf-security-type"/>
<xsl:variable name="productbefore-date" select="before-date"/>
<xsl:variable name="productpartnumber" select="partnumber"/>
<xsl:variable name="productseason" select="season"/>
<xsl:for-each select="variant">
<sku>
<xsl:choose>
<xsl:when test="partnumber">
<PartNumber><xsl:value-of select="partnumber"/></PartNumber>
</xsl:when>
<xsl:when test="$productpartnumber!=''">
<PartNumber><xsl:value-of select="$productpartnumber"/></PartNumber>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="perishable-indicator">
<PartNumber><xsl:value-of select="perishable-indicator"/></PartNumber>
</xsl:when>
<xsl:when test="$productperishable!=''">
<Perishable><xsl:value-of select="$productperishable"/></Perishable>
</xsl:when>
</xsl:choose>
</sku>
</xsl:for-each>
</Product>
</xsl:template>
</xsl:stylesheet>
但是如果我们需要迭代输入xml中存在的几个项目和变体,转换过程需要花费很多时间。任何输入都会有很大的帮助。
答案 0 :(得分:0)
显示的编码技术将执行很长时间,因为XSLT引擎被迫使用编码循环,而不是使用内置的渲染引擎,并且许多值首先被复制到变量而不是立即复制到输出流。
注意xslt渲染引擎在使用其他编码技术时会自动循环所有元素。将XSLT视为渲染引擎的规范,而不是编程语言。在这种编码技术中,<xsl:apply-templates>
(而不是<xsl:for-each
&gt;)告诉渲染引擎继续使用它在实际上下文中遇到的任何XML标记。
默认的XSLT模板创建输入的精确副本:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="@*|*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如您所见,此样式表中没有<xsl:for-each>
命令。您可以使用此规范创建已编译的XSLT渲染,并自行检查运行时的差异。
现在您可以添加转换模板。
如果我正确理解您的规格,您想添加
<xsl:template match="item">
<Product>
<xsl:apply-templates select="variant"/>
</Product>
</xsl:template>
<xsl:template match="variant">
<sku>
<xsl:choose>
<xsl:when test="partnumber != ''">
<xsl:apply-templates select="partnumber"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="../partnumber"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="perishable-indicator!= ''">
<xsl:apply-templates select="perishable-indicator"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="../perishable-indicator"/>
</xsl:otherwise>
</xsl:choose>
</sku>
</xsl:template>
这应该涵盖基础知识。使用此规范编译xslt处理器,并告诉我这是否比当前进程更快。
接下来要与输出规范完全兼容,您应该创建另外两个格式化模板来重命名生成的标记:
<xsl:template match="partnumber">
<PartNumber>
<xsl:apply-templates/>
</PartNumber>
</xsl:template>
<xsl:template match="perishable-indicator">
<Perishable>
<xsl:apply-templates/>
</Perishable>
</xsl:template>
这会创建输出
<document>
<Product>
<sku>
<PartNumber>4</PartNumber>
<Perishable>N</Perishable>
</sku>
</Product>
</document>