我想写一个xsl转换,但我被困在“计数器”部分。 这基本上就是我想做的事情:
输入文件:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Pallets>
<Pallet>
<Line>
<Product>test</Product>
</Line>
<Line>
<Product>test2</Product>
</Line>
</Pallet>
<Pallet>
<Line>
<Product>test_1</Product>
</Line>
<Line>
<Product>test_2</Product>
</Line>
</Pallet>
</Pallets>
</root>
这就是我想要的输出:
<?xml version="1.0" encoding="utf-8"?>
<Result>
<Pallet>
<ID>2</ID> ==> This is a counter that increments starting from 2
<ID2>1</ID2> ==> Always "1"
<Line>
<ID>3</ID> ==> The counter from above that increments
<ParentID>2</ParentID> ==> PalletID (ID from above the loop)
<Name>test</Name>
</Line>
<Line>
<ID>4</ID> ==> The counter from above that increments
<ParentID>2</ParentID> ==> PalletID
<Name>test2</Name>
</Line>
</Pallet>
<Pallet>
<ID>5</ID> ==> The counter from above that increments
<ID2>1</ID2> ==> Always "1"
<Line>
<ID>6</ID> ==> The counter from above that increments
<ParentID>5</ParentID> ==> PalletID
<Name>test_1</Name>
</Line>
<Line>
<ID>7</ID> ==> The counter from above that increments
<ParentID>5</ParentID> ==> PalletID
<Name>test_2</Name>
</Line>
</Pallet>
</Result>
任何人都可以帮我吗? 这是我到目前为止,但正如您将看到的,palletId的计数器不正确。第二个托盘ID应该是ID = 5而不是3:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Result>
<xsl:for-each select="root/Pallets/Pallet">
<xsl:variable name="counter" select="1" />
<Pallet>
<xsl:variable name="Parentcounter" select="position() + $counter" />
<ID>
<xsl:value-of select="$Parentcounter"/>
</ID>
<ID2>1</ID2>
<xsl:for-each select="Line">
<Line>
<ID>
<xsl:value-of select="$Parentcounter + position()"/>
</ID>
<ParentID>
<xsl:value-of select="$Parentcounter"/>
</ParentID>
<Name>
<xsl:value-of select="Product"/>
</Name>
</Line>
</xsl:for-each>
</Pallet>
</xsl:for-each>
</Result>
</xsl:template>
</xsl:stylesheet>
提前致谢。
答案 0 :(得分:1)
您只需计算前面托盘和行的数量,即可获得托盘元素的 ID 元素
<xsl:variable name="id" select="count(preceding::Pallet|preceding::Line) + 2" />
<ID><xsl:value-of select="$id" /></ID>
如果您在匹配行元素的模板中将其作为参数传递,则行元素的 ID 将如下所示(其中) $ parentID包含父级的id
<ID><xsl:value-of select="$ParentID + count(preceding-sibling::Line) + 1" /></ID>
因此,以下XSLT应该产生所需的输出
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Pallets">
<Result>
<xsl:apply-templates select="Pallet" />
</Result>
</xsl:template>
<xsl:template match="Pallet">
<xsl:variable name="id" select="count(preceding::Pallet|preceding::Line) + 2" />
<Pallet>
<ID><xsl:value-of select="$id" /></ID>
<ID2>1</ID2>
<xsl:apply-templates select="Line">
<xsl:with-param name="ParentID" select="$id" />
</xsl:apply-templates>
</Pallet>
</xsl:template>
<xsl:template match="Line">
<xsl:param name="ParentID" />
<Line>
<ID><xsl:value-of select="$ParentID + count(preceding-sibling::Line) + 1" /></ID>
<ParentID><xsl:value-of select="$ParentID" /></ParentID>
<Name><xsl:value-of select="Product" /></Name>
</Line>
</xsl:template>
</xsl:stylesheet>
然而,对于更大数量的托盘和物品来说,这不一定有效,因为它必须重复计算更多的前面元素(基本上反复计算相同的东西)。另一种方法是使用递归模板,每次将Pallet的ID的运行总和作为参数传递。试试这个XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Pallets">
<Result>
<xsl:apply-templates select="Pallet[1]"/>
</Result>
</xsl:template>
<xsl:template match="Pallet">
<xsl:param name="id" select="2"/>
<Pallet>
<ID>
<xsl:value-of select="$id"/>
</ID>
<ID2>1</ID2>
<xsl:apply-templates select="Line[1]">
<xsl:with-param name="parentID" select="$id"/>
</xsl:apply-templates>
</Pallet>
<xsl:apply-templates select="following-sibling::Pallet[1]">
<xsl:with-param name="id" select="$id + count(Line) + 1"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Line">
<xsl:param name="parentID"/>
<xsl:param name="id" select="$parentID + 1"/>
<Line>
<ID>
<xsl:value-of select="$id"/>
</ID>
<ParentID>
<xsl:value-of select="$parentID"/>
</ParentID>
<Name>
<xsl:value-of select="Product" />
</Name>
</Line>
<xsl:apply-templates select="following-sibling::Line[1]">
<xsl:with-param name="parentID" select="$parentID"/>
<xsl:with-param name="id" select="$id + 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
这也会产生相同的输出
<Result>
<Pallet>
<ID>2</ID>
<ID2>1</ID2>
<Line>
<ID>3</ID>
<ParentID>2</ParentID>
<Name>test</Name>
</Line>
<Line>
<ID>4</ID>
<ParentID>2</ParentID>
<Name>test2</Name>
</Line>
</Pallet>
<Pallet>
<ID>5</ID>
<ID2>1</ID2>
<Line>
<ID>6</ID>
<ParentID>5</ParentID>
<Name>test_1</Name>
</Line>
<Line>
<ID>7</ID>
<ParentID>5</ParentID>
<Name>test_2</Name>
</Line>
</Pallet>
</Result>
答案 1 :(得分:0)
使用
<xsl:number level="any" count="Pallet|Line"/>
因为你从2开始,你必须把它放在一个变量中并加一个。