我有一个XSL文件,用于从多个源转换/构建XML文件,其中需要动态更新多个元素和属性。我想知道这种情况是否应该在带有参数的<call-template/>
块中起作用。
当我将外部文件引用作为参数传递时,&#34;代码&#34; EXPORT/Top/Shapes/Shape/Material
下的属性未更新:
<xsl:template match="Shapes">
<xsl:copy>
<xsl:for-each select="document('..\TempReportData\TextXML_Output.xml')/Job/Benchtops/Benchtop">
<xsl:apply-templates select="document('..\DesignMaster\EmptyShapeElement.xml')" />
<xsl:call-template name="updateMaterial">
<xsl:with-param name="mCode" select="./Top_number"/>
</xsl:call-template>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template name="updateMaterial" match="@Code[parent::Material]">
<xsl:param name="mCode"/>
<xsl:attribute name="Code">
<xsl:value-of select="$mCode">
</xsl:attribute>
</xsl:template>
这是期望的结果,<Material></Material>
元素中的Code属性从外部文件更新:
<?xml version="1.0"?>
<EXPORT>
<Top Id="1" Code="B90512">
<Shapes>
<!--Shape-->
<Shape Id="1" Code="Penisola">
<!--Material-->
<Material Code="TOP(2257)"></Material>
</Shape>
<!--Shape-->
<Shape Id="1" Code="Penisola">
<!--Material-->
<Material Code="TOP(2260)"></Material>
</Shape>
</Shapes>
</Top>
</EXPORT>
XML文件TextXML_Output.xml是:
<?xml version="1.0"?>
<Job>
<Job_Number>B90512</Job_Number>
<Job_Address>2nd Floor/ 28-32 Albert Road VIC 3205</Job_Address>
<Benchtops>
<Benchtop>
<Top_number>TOP(2257)</Top_number>
</Benchtop>
<Benchtop>
<Top_number>TOP(2260)</Top_number>
</Benchtop>
</Benchtops>
</Job>
在使用多个模板和文件时,我有点迷失,但在我看来,这应该可行,但它没有。
答案 0 :(得分:1)
您的Shapes
匹配模板
<xsl:template match="Shapes">
<xsl:copy>
<xsl:for-each select="document('..\TempReportData\TextXML_Output.xml')/Job/Benchtops/Benchtop">
<xsl:apply-templates select="document('..\DesignMaster\EmptyShapeElement.xml')" />
<xsl:call-template name="updateMaterial">
<xsl:with-param name="mCode" select="./Top_number"/>
</xsl:call-template>
</xsl:for-each>
</xsl:copy>
</xsl:template>
首先在输出中创建一个Shapes
元素。然后迭代另一个文档中的所有Benchtop
元素,并为每个元素复制一个“Empty Shape Xml”作为您创建的Shapes
元素的子元素。但是,您调用updateMaterial
模板,该模板添加了一个属性。这实际上会尝试在您之前创建的父Shapes
元素上创建一个属性,但是根据W3C Specification ...
在添加子项后向元素添加属性 它;实现可以发出错误信号或忽略错误 属性。
因此,在您的情况下,看起来XSLT处理器忽略了属性,而不是抛出错误。
但是从查看您要实现的内容来看,您似乎希望将该属性添加到Material
元素中,该元素是您正在复制的“EmptyShapeElement.xml”的一部分。
您可以做的是更改您的身份模板,我认为您的完整XSLT正在使用该模板来携带mCode
参数....
<xsl:template match="@*|node()">
<xsl:param name="mCode"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="mCode" select="$mCode" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
然后在选择“EmptyShapeElement.xml”时将Top_Number
值作为此参数传递
<xsl:apply-templates select="$EmptyShapeElement">
<xsl:with-param name="mCode" select="Top_number" />
</xsl:apply-templates>
最后,您现有的属性模板不需要立即命名
<xsl:template match="Material/@Code">
<xsl:param name="mCode"/>
<xsl:attribute name="Code">
<xsl:value-of select="$mCode" />
</xsl:attribute>
</xsl:template>
(这是假设您要替换的“EmptyShapeElement.xml Material
Code”属性中的does indeed have an existing
元素。
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:variable name="TextXML_Output" select="document('..\TempReportData\TextXML_Output.xml')" />
<xsl:variable name="EmptyShapeElement" select="document('..\DesignMaster\EmptyShapeElement.xml')" />
<xsl:template match="@*|node()">
<xsl:param name="mCode"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="mCode" select="$mCode" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Shapes">
<xsl:copy>
<xsl:for-each select="$TextXML_Output/Job/Benchtops/Benchtop">
<xsl:apply-templates select="$EmptyShapeElement">
<xsl:with-param name="mCode" select="Top_number" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="Material/@Code">
<xsl:param name="mCode"/>
<xsl:attribute name="Code">
<xsl:value-of select="$mCode" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>