我有一个输入xml,它具有以下结构,
<VEN>
<CUS>
<MEM>
<MEM>
<MEM>
</CUS>
<CUS>
<MEM>
<MEM>
<MEM>
</CUS>
每个节点在输入xml中多次出现。每个MEM都有一个@ CLM01属性 必须根据MEM节点的每20次出现分配值的节点。从第一个VEN / CUS开始,如果MEM有55个节点,那么前20个节点的@ CLM01值为'1',对于相同的VEN / CUS组合,接下来的20个节点将具有值'2',剩下的15个节点将将@ CLM01值设为'3'。
对于下一个CUS(假设此CUS有30个MEM节点)在相同VEN下,前20个MEM节点的@ CLM01值为'4',接下来的10个MEM将具有值为'5'的@ CLM01。这继续.....我希望我很清楚我想要实现的目标。
感谢。可能吗?使用xslt 1.0
以下是示例输入
<Data>
<VEN vendorId= "v1">
<CUS custId = "c1">
<MEM memId="m1" CLM01=""/>
<MEM memId="m2" CLM01=""/>
<MEM memId="m3" CLM01=""/>
<MEM memId="m4" CLM01=""/>
<MEM memId="m5" CLM01=""/>
</CUS>
<CUS custId = "c2">
<MEM memId="m11" CLM01=""/>
<MEM memId="m12" CLM01=""/>
<MEM memId="m13" CLM01=""/>
<MEM memId="m14" CLM01=""/>
<MEM memId="m15" CLM01=""/>
<MEM memId="m16" CLM01=""/>
<MEM memId="m17" CLM01=""/>
<MEM memId="m18" CLM01=""/>
</CUS>
</VEN>
<VEN vendorId= "v2">
<CUS custId = "c1">
<MEM memId="m4" CLM01=""/>
<MEM memId="m5" CLM01=""/>
<MEM memId="m6" CLM01=""/>
<MEM memId="m7" CLM01=""/>
<MEM memId="m8" CLM01=""/>
</CUS>
<CUS custId = "c1">
<MEM memId="m33" CLM01=""/>
<MEM memId="m44" CLM01=""/>
<MEM memId="m55" CLM01=""/>
<MEM memId="m66" CLM01=""/>
<MEM memId="m77" CLM01=""/>
<MEM memId="m88" CLM01=""/>
<MEM memId="m99" CLM01=""/>
<MEM memId="m11" CLM01=""/>
</CUS>
</VEN>
期望的输出(而不是每3次出现的MEM节点发生20次)
<Data>
<VEN vendorId= "v1">
<CUS custId = "c1">
<MEM memId="m1" CLM01="1"/>
<MEM memId="m2" CLM01="1"/>
<MEM memId="m3" CLM01="1"/>
<MEM memId="m4" CLM01="2"/>
<MEM memId="m5" CLM01="2"/>
</CUS>
<CUS custId = "c2">
<MEM memId="m11" CLM01="3"/>
<MEM memId="m12" CLM01="3"/>
<MEM memId="m13" CLM01="3"/>
<MEM memId="m14" CLM01="4"/>
<MEM memId="m15" CLM01="4"/>
<MEM memId="m16" CLM01="4"/>
<MEM memId="m17" CLM01="5"/>
<MEM memId="m18" CLM01="5"/>
</CUS>
</VEN>
<VEN vendorId= "v2">
<CUS custId = "c1">
<MEM memId="m4" CLM01="6"/>
<MEM memId="m5" CLM01="6"/>
<MEM memId="m6" CLM01="6"/>
<MEM memId="m7" CLM01="7"/>
<MEM memId="m8" CLM01="7"/>
</CUS>
<CUS custId = "c1">
<MEM memId="m33" CLM01="8"/>
<MEM memId="m44" CLM01="8"/>
<MEM memId="m55" CLM01="8"/>
<MEM memId="m66" CLM01="9"/>
<MEM memId="m77" CLM01="9"/>
<MEM memId="m88" CLM01="9"/>
<MEM memId="m99" CLM01="10"/>
<MEM memId="m11" CLM01="10"/>
</CUS>
</VEN>
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pSize" select="3"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates/>
</xsl:variable>
<xsl:variable name="vPass2" select=
"ext:node-set($vrtfPass1)"/>
<xsl:apply-templates select="$vPass2/*" mode="pass2"/>
</xsl:template>
<xsl:template match=
"MEM[not(following-sibling::MEM)]">
<xsl:call-template name="identity"/>
<xsl:variable name="vPos" select=
"count(preceding-sibling::MEM)+1"/>
<xsl:variable name="pTimes"
select="$pSize - ($vPos mod $pSize)"/>
<xsl:call-template name="genMems">
<xsl:with-param name="pTimes" select="$pTimes"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="genMems">
<xsl:param name="pTimes"/>
<xsl:if test="$pTimes >0">
<MEM fake="yes"/>
<xsl:call-template name="genMems">
<xsl:with-param name="pTimes" select="$pTimes -1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2" name="identity2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="MEM/@CLM01" mode="pass2">
<xsl:attribute name="CLM01">
<xsl:variable name="vNum">
<xsl:number count="MEM" level="any"/>
</xsl:variable>
<xsl:value-of select=
"ceiling($vNum div $pSize)"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="MEM[@fake='yes']" mode="pass2"/>
</xsl:stylesheet>
应用于提供的XML文档时:
<Data>
<VEN vendorId= "v1">
<CUS custId = "c1">
<MEM memId="m1" CLM01=""/>
<MEM memId="m2" CLM01=""/>
<MEM memId="m3" CLM01=""/>
<MEM memId="m4" CLM01=""/>
<MEM memId="m5" CLM01=""/>
</CUS>
<CUS custId = "c2">
<MEM memId="m11" CLM01=""/>
<MEM memId="m12" CLM01=""/>
<MEM memId="m13" CLM01=""/>
<MEM memId="m14" CLM01=""/>
<MEM memId="m15" CLM01=""/>
<MEM memId="m16" CLM01=""/>
<MEM memId="m17" CLM01=""/>
<MEM memId="m18" CLM01=""/>
</CUS>
</VEN>
<VEN vendorId= "v2">
<CUS custId = "c1">
<MEM memId="m4" CLM01=""/>
<MEM memId="m5" CLM01=""/>
<MEM memId="m6" CLM01=""/>
<MEM memId="m7" CLM01=""/>
<MEM memId="m8" CLM01=""/>
</CUS>
<CUS custId = "c1">
<MEM memId="m33" CLM01=""/>
<MEM memId="m44" CLM01=""/>
<MEM memId="m55" CLM01=""/>
<MEM memId="m66" CLM01=""/>
<MEM memId="m77" CLM01=""/>
<MEM memId="m88" CLM01=""/>
<MEM memId="m99" CLM01=""/>
<MEM memId="m11" CLM01=""/>
</CUS>
</VEN>
</Data>
会产生想要的正确结果:
<Data>
<VEN vendorId="v1">
<CUS custId="c1">
<MEM memId="m1" CLM01="1"/>
<MEM memId="m2" CLM01="1"/>
<MEM memId="m3" CLM01="1"/>
<MEM memId="m4" CLM01="2"/>
<MEM memId="m5" CLM01="2"/>
</CUS>
<CUS custId="c2">
<MEM memId="m11" CLM01="3"/>
<MEM memId="m12" CLM01="3"/>
<MEM memId="m13" CLM01="3"/>
<MEM memId="m14" CLM01="4"/>
<MEM memId="m15" CLM01="4"/>
<MEM memId="m16" CLM01="4"/>
<MEM memId="m17" CLM01="5"/>
<MEM memId="m18" CLM01="5"/>
</CUS>
</VEN>
<VEN vendorId="v2">
<CUS custId="c1">
<MEM memId="m4" CLM01="6"/>
<MEM memId="m5" CLM01="6"/>
<MEM memId="m6" CLM01="6"/>
<MEM memId="m7" CLM01="7"/>
<MEM memId="m8" CLM01="7"/>
</CUS>
<CUS custId="c1">
<MEM memId="m33" CLM01="8"/>
<MEM memId="m44" CLM01="8"/>
<MEM memId="m55" CLM01="8"/>
<MEM memId="m66" CLM01="9"/>
<MEM memId="m77" CLM01="9"/>
<MEM memId="m88" CLM01="9"/>
<MEM memId="m99" CLM01="10"/>
<MEM memId="m11" CLM01="10"/>
</CUS>
</VEN>
</Data>
<强>解释强>:
双程转换。
第一次传递会添加假MEM
元素,以便结果中的每个CUS
元素都有MEM
个孩子,其数量是$pSize
的倍数。
第二遍:
使用并覆盖 identity rule 。
使用 <xsl:number>
通过MEM
获取level="any"
元素的正确编号。
答案 1 :(得分:1)
只是为了好玩,一次转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="pSize" select="3"/>
<xsl:template match="node()|@*">
<xsl:param name="pOffset" select="0"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pOffset" select="$pOffset"/>
<xsl:with-param name="pPosition" select="position()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="VEN|CUS">
<xsl:param name="pOffset" select="0"/>
<xsl:variable name="vIsVEN" select="self::VEN"/>
<xsl:copy>
<xsl:apply-templates
select="@*|node()[position()=1 and $vIsVEN or not($vIsVEN)]">
<xsl:with-param name="pOffset" select="$pOffset"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]">
<xsl:with-param name="pOffset"
select="$pOffset + count(.//MEM[position() mod $pSize = 1])"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="MEM/@CLM01">
<xsl:param name="pPosition" select="1"/>
<xsl:param name="pOffset" select="0"/>
<xsl:attribute name="{name()}">
<xsl:value-of
select="$pOffset + ceiling(($pPosition - 1) div $pSize)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
输出:
<Data>
<VEN vendorId="v1">
<CUS custId="c1">
<MEM memId="m1" CLM01="1"></MEM>
<MEM memId="m2" CLM01="1"></MEM>
<MEM memId="m3" CLM01="1"></MEM>
<MEM memId="m4" CLM01="2"></MEM>
<MEM memId="m5" CLM01="2"></MEM>
</CUS>
<CUS custId="c2">
<MEM memId="m11" CLM01="3"></MEM>
<MEM memId="m12" CLM01="3"></MEM>
<MEM memId="m13" CLM01="3"></MEM>
<MEM memId="m14" CLM01="4"></MEM>
<MEM memId="m15" CLM01="4"></MEM>
<MEM memId="m16" CLM01="4"></MEM>
<MEM memId="m17" CLM01="5"></MEM>
<MEM memId="m18" CLM01="5"></MEM>
</CUS>
</VEN>
<VEN vendorId="v2">
<CUS custId="c1">
<MEM memId="m4" CLM01="6"></MEM>
<MEM memId="m5" CLM01="6"></MEM>
<MEM memId="m6" CLM01="6"></MEM>
<MEM memId="m7" CLM01="7"></MEM>
<MEM memId="m8" CLM01="7"></MEM>
</CUS>
<CUS custId="c1">
<MEM memId="m33" CLM01="8"></MEM>
<MEM memId="m44" CLM01="8"></MEM>
<MEM memId="m55" CLM01="8"></MEM>
<MEM memId="m66" CLM01="9"></MEM>
<MEM memId="m77" CLM01="9"></MEM>
<MEM memId="m88" CLM01="9"></MEM>
<MEM memId="m99" CLM01="10"></MEM>
<MEM memId="m11" CLM01="10"></MEM>
</CUS>
</VEN>
<VEN vendorId="v2">
<CUS custId="c1">
<MEM memId="m4" CLM01="1"></MEM>
<MEM memId="m5" CLM01="1"></MEM>
<MEM memId="m6" CLM01="1"></MEM>
<MEM memId="m7" CLM01="2"></MEM>
<MEM memId="m8" CLM01="2"></MEM>
</CUS>
<CUS custId="c1">
<MEM memId="m33" CLM01="3"></MEM>
<MEM memId="m44" CLM01="3"></MEM>
<MEM memId="m55" CLM01="3"></MEM>
<MEM memId="m66" CLM01="4"></MEM>
<MEM memId="m77" CLM01="4"></MEM>
<MEM memId="m88" CLM01="4"></MEM>
<MEM memId="m99" CLM01="5"></MEM>
<MEM memId="m11" CLM01="5"></MEM>
</CUS>
</VEN>
</Data>
注意:混合儿童和兄弟姐妹遍历。隧道参数。