xml - XSL 中每个循环的条件 XSL
问题描述
我在这里有一个场景,我需要使用 XSLT 生成一个带有 newnode1 的 xml,方法是读取一个可以以“n”次传递的 xml node1 和一个也可以作为“n”次传递的 node2。这是我的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 中使用了 xsl:for each,并在每次执行 xsl:for each 时使用了 if 条件来检查行 num。是否有一个简单的逻辑可以得到我的结果,除了从我尝试过的。
提前致谢。
解决方案
您遇到的一个问题是如何定义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
)
推荐阅读
- javascript - 意外添加空格
- amazon-web-services - 如何将别名传递给 aws 计划的 lambda
- events - Vuex:如何从动作订阅事件
- python - 如何使用python填充excel中的背景单元格?
- android - play-services-ads:18.1.0 在 Android 4 上导致致命错误
- excel - 如何通过 VBA 使用来自另一列的信息在 Excel 2013 中创建列?
- java - String#replaceAll 与 StringUtils#replace()
- c - GtkProgressBar 在 Ubuntu 18.04 中跳动?
- java - 在java中,如果使用同步,即使考虑到不一致的值
- javascript - 如何将上下文从视图传递到 JS 文件 Django