这是我的要求我需要编写一个XSLT来根据出现的情况转换节点名称看看我的例子
XML现在:
<Orders>
<Order>
<OrderNo>ABC</OrderNo>
<ItemDetails>
<Name>Shirt</Name>
<Name>Socks</Name>
<ItemPrice>30</ItemPrice>
<ItemPrice>40</ItemPrice>
</ItemDetails>
</Order>
</Orders>
需要XML
<Orders>
<Order>
<OrderNo>ABC</OrderNo>
<ItemDetails>
<Name1>Shirt</Name>
<Name2>Socks</Name>
<ItemPrice1>30</ItemPrice>
<ItemPrice2>40</ItemPrice>
</ItemDetails>
</Order>
</Orders>
检查名称和项目价格风险。像这样我在一个xml的ORDERS中有100个订单
答案 0 :(得分:1)
这可以使用基于身份转换的样式表来复制大部分未更改的XML,只需调整您想要更改的小位:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<xsl:template match="ItemDetails/*">
<xsl:element name="{name()}{count(
preceding-sibling::*[name() = name(current())]) + 1}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
如果你想单独留下每个元素的第一个,并从第二个开始编号,那么你可以通过调整模板匹配模式在XSLT 2.0中做到这一点:
<xsl:template match="ItemDetails/*[preceding-sibling::*[name() = name(current())]]">
<xsl:element name="{name()}{count(
preceding-sibling::*[name() = name(current())])}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
但是在XSLT 1.0中,你不能在current()
模式中使用match
,所以你必须在模板体内进行检查,例如。
<xsl:template match="@*|node()" name="ident">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<xsl:template match="ItemDetails/*">
<xsl:choose>
<xsl:when test="preceding-sibling::*[name() = name(current())]">
<xsl:element name="{name()}{count(
preceding-sibling::*[name() = name(current())])}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- this is the first element with this name, so revert to the
identity behaviour -->
<xsl:call-template name="ident" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
在更一般的层面上,这是一种相当糟糕的XML格式选择 - 对于表示相同类型数据的元素使用相同的名称更为常见,并且通过嵌套而不是定位来表达不同元素之间的依赖关系,例如
<ItemDetails>
<Item>
<Name>Shirt</Name>
<Price>30</Price>
</Item>
<Item>
<Name>Socks</Name>
<Price>40</Price>
</Item>
</ItemDetails>