我有这样的场景,我需要使用XSLT通过读取xn node1来生成xml,该xml node1可以传递'n'次,而node2也可以传递'n'次。 这是我的xml的样子..
<?xml version="1.0" encoding="UTF-8"?>
<Node>
<Node_1>
<Line>1</Line>
<Text>First node1</Text>
<Desc>Desc1</Desc>
<Cust>Cust1</Cust>
</Node_1>
<Node_1>
<Line>2</Line>
<Text>First node2</Text>
<Desc>Desc2</Desc>
<Cust>Cust2</Cust>
</Node_1>
<Node_2>
<Line>1</Line>
<ReadInd>Y</ReadInd>
<WriteInd>Y</WriteInd>
<UpdateInd>Y</UpdateInd>
</Node_2>
<Node_2>
<Line>2</Line>
<ReadInd>N</ReadInd>
<WriteInd>N</WriteInd>
<UpdateInd>N</UpdateInd>
</Node_2>
</Node>
下面是我为此实现的XSLT代码,但我确实看到了运行时的性能问题,我的输入XML Node_1和Node_2重复超过100个循环需要更多时间。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<xsl:for-each select="Node/Node_1">
<xsl:variable name="line" select="//Node_1/Line"/>
<line><xsl:value-of select="Line"/></line>
<text><xsl:value-of select="Text"/></text>
<desc><xsl:value-of select="Desc"/></desc>
<cust><xsl:value-of select="Cust"/></cust>
<xsl:for-each select="/Node/Node_2">
<xsl:if test="Line=$line">
<readind><xsl:value-of select="ReadInd"/></readind>
<writeind><xsl:value-of select="WriteInd"/></writeind>
<updateind><xsl:value-of select="UpdateInd"/></updateind>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
正如你所看到的,我已经使用了xsl:for each in xsl:for each,以及if条件来检查每次xsl:for每次执行时的行号。是否有一个简单的逻辑来获取我的结果,除了我尝试的。
提前致谢。
答案 0 :(得分:0)
您遇到的一个问题是如何定义line
变量
<xsl:variable name="line" select="//Node_1/Line"/>
这将选择XML中所有Line
元素下的所有Node_1
元素。这意味着当您执行<xsl:if test="Line=$line">
时,无论您正在处理什么Node_1
,这都会返回true,因此您将输出所有Node_2
个元素。
您应该像这样定义
但是,为了有效查找,请考虑使用密钥
<xsl:key name="node2" match="Node_2" use="Line" />
然后你可以像这样选择Node_2
元素
<xsl:for-each select="key('node2', $line)">
或者甚至是这样,因为在这种情况下不需要变量,因为此时当前节点仍然是Node_1
<xsl:for-each select="key('node2', Line)">
试试这个XSLT
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="node2" match="Node_2" use="Line" />
<xsl:template match="/">
<xsl:for-each select="Node/Node_1">
<node>
<line><xsl:value-of select="Line"/></line>
<text><xsl:value-of select="Text"/></text>
<desc><xsl:value-of select="Desc"/></desc>
<cust><xsl:value-of select="Cust"/></cust>
<xsl:for-each select="key('node2', Line)">
<subnode>
<readind><xsl:value-of select="ReadInd"/></readind>
<writeind><xsl:value-of select="WriteInd"/></writeind>
<updateind><xsl:value-of select="UpdateInd"/></updateind>
</subnode>
</xsl:for-each>
</node>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(注意,我添加了node
和subnode
标记的创建,以便更容易看到与每个Node_2
相关联的正确Node_1
元素