XSLT 按条件对标记化值进行分组
XSLT Grouping tokenized values by condition
我很难将重复元素分组到新的 xml。
我的输入文件是
<Load>
<DataArea>
<tag>
<row>A,Header</row>
</tag>
<tag>
<row>B,20190701</row>
</tag>
<tag>
<row>C,12345, 100.00, 200.00</row>
</tag>
<tag>
<row>D,001, 25.00</row>
</tag>
<tag>
<row>D,002, 35.00</row>
</tag>
<tag>
<row>D,003, 45.00</row>
</tag>
<tag>
<row>B,20190702</row>
</tag>
<tag>
<row>C,12345, 300.00, 400.00</row>
</tag>
<tag>
<row>D,004, 55.00</row>
</tag>
<tag>
<row>D,005, 65.00</row>
</tag>
<tag>
<row>D,006, 75.00</row>
</tag>
</DataArea>
</Load>
我必须标记逗号分隔的元素值,并想将其转换为下面的 xml 结构。
<Load>
<DataArea>
<Header>
<A>Header</A>
</Header>
<Line>
<!-- July 1 Record -->
<B>20190701</B>
<C>12345</C>
<D>
<code>001</code>
<amount>25.00</amount>
</D>
<D>
<code>002</code>
<amount>35.00</amount>
</D>
<D>
<code>003</code>
<amount>45.00</amount>
</D>
</Line>
<Line>
<!-- July 2 Record -->
<B>20190702</B>
<C>12345</C>
<D>
<code>004</code>
<amount>55.00</amount>
</D>
<D>
<code>005</code>
<amount>65.00</amount>
</D>
<D>
<code>006</code>
<amount>75.00</amount>
</D>
</Line>
</DataArea>
</Load>
有 2 个 <Lines></Lines>
因为只有两个日期 7 月 1 日 和 7 月 2 日。日期表示为元素 <B>
的值
每个 <Line>
有多个 <D>
我的问题是我无法将 <B><C>
和 <D>
放在一起并用 <Line>
括起来。 <D>
应该属于正确的 <B>
或日期。
下面是我的 xslt 代码。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<Load>
<DataArea>
<Header>
<A>
<xsl:for-each select="Load/DataArea/tag">
<xsl:variable name="col"
select="tokenize(current(),',')" />
<xsl:if test="$col[1] = 'A' ">
<xsl:value-of select="$col[2]" />
</xsl:if>
</xsl:for-each>
</A>
</Header>
<xsl:for-each select="Load/DataArea/tag">
<xsl:variable name="column"
select="tokenize(current(),',')" />
<Line>
<xsl:if test="$column[1] = 'B' ">
<B>
<xsl:value-of select="$column[2]" />
</B>
</xsl:if>
<xsl:if test="$column[1] = 'C' ">
<C>
<xsl:value-of select="$column[2]" />
</C>
</xsl:if>
<xsl:for-each select="../tag">
<xsl:variable name="column"
select="tokenize(current(),',')" />
<xsl:if test="$column[1] = 'D' ">
<D>
<code>
<xsl:value-of select="$column[2]" />
</code>
<amount>
<xsl:value-of select="$column[3]" />
</amount>
</D>
</xsl:if>
</xsl:for-each>
</Line>
</xsl:for-each>
</DataArea>
</Load>
</xsl:template>
</xsl:stylesheet>
我正在获取所有 <D>
的每个循环,而不仅仅是那些属于日期的循环/<B>
重复所有 <D>
和 <Line>
我不确定如何解决这个问题,尤其是我需要对它们进行标记。
如有任何帮助,我将不胜感激。
谢谢。
我认为这可能是具有 group-starting-with
属性的 xsl:for-each-group
的工作。
试试这个 XSLT,我还简化了使用基本 starts-with
功能
获取 A
header 的过程
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<Load>
<DataArea>
<Header>
<A>
<xsl:value-of select="substring-after(Load/DataArea/tag[starts-with(row, 'A,')], ',') " />
</A>
</Header>
<xsl:for-each-group select="Load/DataArea/tag[not(starts-with(row, 'A,'))]" group-starting-with="tag[starts-with(row, 'B,')]">
<Line>
<xsl:for-each select="current-group()">
<xsl:variable name="column" select="tokenize(row,',')" />
<xsl:element name="{$column[1]}">
<xsl:choose>
<xsl:when test="$column[1] = 'B' or $column[1] = 'C'">
<xsl:value-of select="$column[2]" />
</xsl:when>
<xsl:otherwise>
<code>
<xsl:value-of select="$column[2]" />
</code>
<amount>
<xsl:value-of select="$column[3]" />
</amount>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:for-each>
</Line>
</xsl:for-each-group>
</DataArea>
</Load>
</xsl:template>
</xsl:stylesheet>
我很难将重复元素分组到新的 xml。
我的输入文件是
<Load>
<DataArea>
<tag>
<row>A,Header</row>
</tag>
<tag>
<row>B,20190701</row>
</tag>
<tag>
<row>C,12345, 100.00, 200.00</row>
</tag>
<tag>
<row>D,001, 25.00</row>
</tag>
<tag>
<row>D,002, 35.00</row>
</tag>
<tag>
<row>D,003, 45.00</row>
</tag>
<tag>
<row>B,20190702</row>
</tag>
<tag>
<row>C,12345, 300.00, 400.00</row>
</tag>
<tag>
<row>D,004, 55.00</row>
</tag>
<tag>
<row>D,005, 65.00</row>
</tag>
<tag>
<row>D,006, 75.00</row>
</tag>
</DataArea>
</Load>
我必须标记逗号分隔的元素值,并想将其转换为下面的 xml 结构。
<Load>
<DataArea>
<Header>
<A>Header</A>
</Header>
<Line>
<!-- July 1 Record -->
<B>20190701</B>
<C>12345</C>
<D>
<code>001</code>
<amount>25.00</amount>
</D>
<D>
<code>002</code>
<amount>35.00</amount>
</D>
<D>
<code>003</code>
<amount>45.00</amount>
</D>
</Line>
<Line>
<!-- July 2 Record -->
<B>20190702</B>
<C>12345</C>
<D>
<code>004</code>
<amount>55.00</amount>
</D>
<D>
<code>005</code>
<amount>65.00</amount>
</D>
<D>
<code>006</code>
<amount>75.00</amount>
</D>
</Line>
</DataArea>
</Load>
有 2 个 <Lines></Lines>
因为只有两个日期 7 月 1 日 和 7 月 2 日。日期表示为元素 <B>
每个 <Line>
<D>
我的问题是我无法将 <B><C>
和 <D>
放在一起并用 <Line>
括起来。 <D>
应该属于正确的 <B>
或日期。
下面是我的 xslt 代码。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<Load>
<DataArea>
<Header>
<A>
<xsl:for-each select="Load/DataArea/tag">
<xsl:variable name="col"
select="tokenize(current(),',')" />
<xsl:if test="$col[1] = 'A' ">
<xsl:value-of select="$col[2]" />
</xsl:if>
</xsl:for-each>
</A>
</Header>
<xsl:for-each select="Load/DataArea/tag">
<xsl:variable name="column"
select="tokenize(current(),',')" />
<Line>
<xsl:if test="$column[1] = 'B' ">
<B>
<xsl:value-of select="$column[2]" />
</B>
</xsl:if>
<xsl:if test="$column[1] = 'C' ">
<C>
<xsl:value-of select="$column[2]" />
</C>
</xsl:if>
<xsl:for-each select="../tag">
<xsl:variable name="column"
select="tokenize(current(),',')" />
<xsl:if test="$column[1] = 'D' ">
<D>
<code>
<xsl:value-of select="$column[2]" />
</code>
<amount>
<xsl:value-of select="$column[3]" />
</amount>
</D>
</xsl:if>
</xsl:for-each>
</Line>
</xsl:for-each>
</DataArea>
</Load>
</xsl:template>
</xsl:stylesheet>
我正在获取所有 <D>
的每个循环,而不仅仅是那些属于日期的循环/<B>
重复所有 <D>
和 <Line>
我不确定如何解决这个问题,尤其是我需要对它们进行标记。
如有任何帮助,我将不胜感激。
谢谢。
我认为这可能是具有 group-starting-with
属性的 xsl:for-each-group
的工作。
试试这个 XSLT,我还简化了使用基本 starts-with
功能
A
header 的过程
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<Load>
<DataArea>
<Header>
<A>
<xsl:value-of select="substring-after(Load/DataArea/tag[starts-with(row, 'A,')], ',') " />
</A>
</Header>
<xsl:for-each-group select="Load/DataArea/tag[not(starts-with(row, 'A,'))]" group-starting-with="tag[starts-with(row, 'B,')]">
<Line>
<xsl:for-each select="current-group()">
<xsl:variable name="column" select="tokenize(row,',')" />
<xsl:element name="{$column[1]}">
<xsl:choose>
<xsl:when test="$column[1] = 'B' or $column[1] = 'C'">
<xsl:value-of select="$column[2]" />
</xsl:when>
<xsl:otherwise>
<code>
<xsl:value-of select="$column[2]" />
</code>
<amount>
<xsl:value-of select="$column[3]" />
</amount>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:for-each>
</Line>
</xsl:for-each-group>
</DataArea>
</Load>
</xsl:template>
</xsl:stylesheet>