我有一个XML文档,其中包含有关父实体的用户定义信息。我想创建一个XSLT来将XML转换为当前用户定义的列表。 XSLT将需要忽略已删除的元素,添加新元素,并保持用户定义的元素顺序。
示例输入XML:
<InventoryProperties>
<InvProp Name="Weight"
Type="Text"
Alignment="Right">12500</InvProp>
<InvProp Name="Length"
Type="Text"
Alignemnt="Right">20.2</InvProp>
<InvProp Name="GVW"
Type="Text"></InvProp>
</InventoryProperties>
所以现在用户已经更改了收集的数据点,并且不再需要GVW,但是在权重和长度之间添加了高度。到目前为止我所做的是获取我想要的元素并留下我不再需要的元素:
<xsl:apply-templates select="InventoryProperties/InvProp[@Name = 'Weight']"/>
重复当前定义的每个字段。这工作正常,并按预期保持顺序。为了添加新元素,我正在尝试这样的事情:
<xsl:apply-templates select="InventoryProperties[not(InvProp[@Name='Height'])]"/>
<xsl:template name="HeightTemplate"
match="InventoryProperties[not(InvProp[@Name='Height'])]">
<xsl:apply-templates select="@*[not(name()='Height')]|node()"/>
<Property LabelText="HelloWorld" />
</xsl:template>
以及其他几个版本,但没有任何东西可以产生我想要的东西:
<InventoryProperties>
<Property LabelText="Weight"
ControlType="Text">12500</Property>
<Property LabelText="Height"
ControlType="Text"></Property>
<Property LabelText="Length"
ControlType="Text">20.2</Property>
</InventoryProperties>
没有理由更改元素和属性名称,我只是试图分析工作中的内容和不起作用的内容。
答案 0 :(得分:0)
我建议您为要添加到输出的每个字段名称调用命名模板。该命名模板将检查是否存在具有给定Name
属性的元素,如果存在则复制它,如果没有,则创建具有正确属性的存根。
这显示了这个想法
<xsl:template match="InventoryProperties">
<xsl:call-template name="inv-prop">
<xsl:with-param name="name" select="'Weight'"/>
</xsl:call-template>
<xsl:call-template name="inv-prop">
<xsl:with-param name="name" select="'Height'"/>
</xsl:call-template>
<xsl:call-template name="inv-prop">
<xsl:with-param name="name" select="'Length'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="inv-prop">
<xsl:param name="name"/>
<xsl:variable name="selection" select="InvProp[@Name = $name]"/>
<xsl:choose>
<xsl:when test="$selection">
<xsl:copy-of select="$selection"/>
</xsl:when>
<xsl:otherwise>
<InvProp Name="{$name}" Type="Text" Alignment="Right">
<xsl:value-of select="InvProp[@Name = $name]"/>
</InvProp>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<强>输出强>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<InvProp Name="Weight" Type="Text" Alignment="Right">12500</InvProp>
<InvProp Name="Height" Type="Text" Alignment="Right"/>
<InvProp Name="Length" Type="Text" Alignemnt="Right">20.2</InvProp>
</root>
答案 1 :(得分:0)
也许你应该试一试 使用一些钩子忽略或添加元素身份转换。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- ingnore not wonted stuff -->
<xsl:template match ="InvProp[@Name='GVW'] " />
<!-- add missing stuff -->
<xsl:template match ="InvProp[@Name='Weight'] ">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
<xsl:if test="not(following-sibling::InvProp[@Name='Height'])" >
<InvProp Name="Height" Type="Text" Alignment="Right"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>