我需要合并两个XML文档。
<!-- A.xml -->
<cm:Process>
<cm:Other />
<cm:Elements />
<cm:Request>
<!-- stuff -->
</cm:Request>
<cm:ElementCouldBeHereToo />
<cm:Request>
<!-- stuff -->
</cm:Request>
</cm:Process>
<!-- B.xml -->
<gateway-orders>
<response>
<status />
</response>
<response>
<status />
</response>
</gateway-orders>
第一个是原始XML。请求已被撤出并发送到系统,接下来是响应。现在我需要合并这两个并将请求N与响应N匹配,这样我就可以从响应中提取一些信息。 XSL在A.xml上运行并获取B.xml作为参数。首先,我只想在A.xml中的请求中创建B.xml中正确响应的副本。
我遇到的问题是我认为我可以使用position()
,但意识到这不起作用,因为cm:Request
元素与其他元素混合在一起。还有其他方法可以用来匹配这些吗?
这就是我的尝试:
<xsl:import href="identity-transform.xsl" />
<xsl:param name="responses" />
<xsl:template match="cm:Request">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:apply-templates select="$responses/*[1]/*[position()]" />
</xsl:copy>
</xsl:template>
这里有两个问题。
position()
不匹配。有没有办法获得你所在的cm:Request
元素的数量/位置,而不是所有兄弟元素的数量/位置?因此,如果第一个cm:Request
前面有任何元素,那么第一个position()
总是给出1。1
更改blah
,我只会在每个请求中获得第一个响应的副本。我在这做错了什么?希望有人知道我应该在这做什么,因为我现在有点空白而且我的Google-fu让我失望:P
总结,如何将第n个元素与名称{{1}}与参数node-set中的第n个子元素进行匹配?
答案 0 :(得分:1)
这是怎么回事:
<xsl:template match="cm:Request">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:variable name="reqNum" select="count(preceding-sibling::cm:Request | .)" />
<xsl:apply-templates select="$responses/*[1]/response[$reqNum]" />
</xsl:copy>
</xsl:template>
解释一下:
2.其次,我出于某种原因获得每个请求中所有响应的副本。如果我用例如1更改position(),我只会在每个请求中获得第一个响应的副本。我在这里做错了什么?
在这种情况下,position()
的行为实际上与您的想法不同。如果您在该模板中执行此操作:
<xsl:variable name="pos" select="position()" />
然后 $pos
将拥有与其所有兄弟姐妹相关的当前cm:Request
的位置,但在此处:
$responses/*[1]/*[position()]
position()
正在上下文$responses/*[1]/*
中进行评估。因此,对于第一个<response>
,此评估为$responses/*[1]/*[1]
,对于第二个响应,此评估为$responses/*[1]/*[2]
,因此两者始终处于选中状态。
答案 1 :(得分:1)
一种方法应该是
<xsl:template match="cm:Request">
<xsl:variable name="index"><xsl:number/></xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:apply-templates select="$responses/*[1]/*[position() = $index]"/>
</xsl:copy>
</xsl:template>