我想将缺少的节点插入XML,以防它丢失。例如,我想在CustomInformation节点之前添加<Details>
节点。我编写了下面的XSLT转换,但CostPlan节点上的属性没有出现。我哪里错了?
示例数据:
<CostPlan code="test" periodType="MONTHLY" >
<Description/>
<GroupingAttributes>
<GroupingAttribute>cost_type_id</GroupingAttribute>
<GroupingAttribute>transaction_class_id</GroupingAttribute>
<GroupingAttribute>charge_code_id</GroupingAttribute>
</GroupingAttributes>
<CustomInformation>
<ColumnValue name="pra">xyz</ColumnValue>
<ColumnValue name="partition_code">abc</ColumnValue>
</CustomInformation>
</CostPlan>
XSLT转型:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CostPlan[not(Details)]">
<xsl:variable name="elements-after" select="CustomInformation"/>
<xsl:copy>
<xsl:copy-of select="* except $elements-after"/>
<Details/>
<xsl:copy-of select="$elements-after"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出:
<CostPlan> <!-- attributes missing compared to original -->
<Description/>
<GroupingAttributes>
<GroupingAttribute>cost_type_id</GroupingAttribute>
<GroupingAttribute>transaction_class_id</GroupingAttribute>
<GroupingAttribute>charge_code_id</GroupingAttribute>
</GroupingAttributes>
<Details/>
<CustomInformation>
<ColumnValue name="pra">xyz</ColumnValue>
<ColumnValue name="partition_code">abc</ColumnValue>
</CustomInformation>
</CostPlan>
答案 0 :(得分:3)
嗯,匹配CostPlan[not(Details)]
的模板不处理属性。变化:
<xsl:copy-of select="* except $elements-after"/>
为:
<xsl:copy-of select="@* | * except $elements-after"/>
另请注意,您的样式表标记为XSLT 1.0,但您肯定使用的是XSLT 2.0。
在XSLT 1.0中你可以这样做:
<xsl:template match="CostPlan[not(Details)]">
<xsl:copy>
<xsl:copy-of select="@* | *[not(self::CustomInformation)]"/>
<Details/>
<xsl:copy-of select="CustomInformation"/>
</xsl:copy>
</xsl:template>
请注意,$elements-after
变量仅使用一次,因此是多余的(在两个版本中)。
答案 1 :(得分:2)
更短更简单:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CostPlan[not(Details)]/CustomInformation">
<Details/>
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>