我有以下XML输入文档:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
repName="FirstElementTemp"
date="10-05-2001">
<element1>
<subElement>
SomeData
</subElement>
</element1>
<element2>
<subElement type="2"/>
</element2>
</report>
我想在<valueIs>
元素之前添加一个名为<element1>
的新元素,数据来自另一个我用作<xsl:param>
的XML输入文件。
所以基本上这是我想要获得的输出:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
repName="FirstElementTemp"
date="10-05-2001">
<valueIs>FIRST DATA</valueIs>
<element1>
<subElement>
SomeData
</subElement>
</element1>
<element2>
<subElement type="2"/>
</element2>
</report>
这是我正在使用的XSLT代码(第二个XML文档内联为):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://jasperreports.sourceforge.net/jasperreports"
xmlns:jsp="http://jasperreports.sourceforge.net/jasperreports"
exclude-result-prefixes="xs jsp"
expand-text="yes"
version="3.0">
<xsl:param name="doc2" xmlns="">
<secondDoc>
<elementTemps>
<elemTemp ID="1" name="FirstElementTemp" />
<elemTemp ID="2" name="SecondTemplate" />
</elementTemps>
<elementReps>
<elemRep tmpID="1" name="FirstElementRep" >
<value>FIRST DATA</value>
</elemRep>
<elemRep tmpID="2" name="SecondTemplate">
<value>SECOND DATA</value>
</elemRep>
</elementReps>
</secondDoc>
</xsl:param>
<xsl:output indent="yes" cdata-section-elements="cDataElement"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="key1" match="elemTemp" use="@name" xpath-default-namespace=""/>
<xsl:key name="key2" match="elemRep" use="@tmpID" xpath-default-namespace=""/>
<xsl:template match="report">
<xsl:next-match/>
<xsl:variable name="temp" select="key('key1', @repName, $doc2)"/>
<xsl:variable name="rep" select="key('key2', $temp/@ID, $doc2)"/>
<valueIs>
<xsl:value-of select="$rep/value" xpath-default-namespace=""/>
</valueIs>
</xsl:template>
</xsl:stylesheet>
哪个会产生以下结果:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
repName="FirstElementTemp"
date="10-05-2001">
<element1>
<subElement>
SomeData
</subElement>
</element1>
<element2>
<subElement type="2"/>
</element2>
</report>
<valueIs>FIRST DATA</valueIs>
我知道我不能在此处使用<xsl:next-match>
,但是由于我正在使用<report>
,所以我需要将keys
元素作为当前节点,
有什么方法可以专门在<valueIs>
文档之前创建<element1>
文档吗?我需要将<valueIs>
元素保留在<report>
元素内,因为该元素是根节点...
谢谢!
Alexandre Jacinto
答案 0 :(得分:0)
与其依靠<xsl:next-match>
来完成所有工作,不如将某些identity-template逻辑放入模板中以复制元素,将模板应用到其属性,插入自定义内容,以及然后将模板应用于子节点:
<xsl:template match="report">
<xsl:variable name="temp" select="key('key1', @repName, $doc2)"/>
<xsl:variable name="rep" select="key('key2', $temp/@ID, $doc2)"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<valueIs>
<xsl:value-of select="$rep/value" xpath-default-namespace=""/>
</valueIs>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
或者,您可以更改模板以使其与第一个子元素report/*[1]
匹配,然后在从key1
中进行选择时调整XPath,以跳至report
元素以选择它。 @repName
,生成新元素,然后使用xsl:next-match
。
<xsl:template match="report/*[1]">
<xsl:variable name="temp" select="key('key1', ../@repName, $doc2)"/>
<xsl:variable name="rep" select="key('key2', $temp/@ID, $doc2)"/>
<valueIs>
<xsl:value-of select="$rep/value" xpath-default-namespace=""/>
</valueIs>
<xsl:next-match/>
</xsl:template>