XML - XSLT - 使用辅助文档和 <xsl:next-match>
XML - XSLT - Working with auxiliar document and <xsl:next-match>
我有以下 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>
我想在 <element1>
元素之前添加一个名为 <valueIs>
的新元素,数据来自我用作 [=18] 的第二个 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
我是使用,
有什么方法可以在 <element1>
文件之前专门创建 <valueIs>
文件吗?我需要将 <valueIs>
元素保留在 <report>
元素内,因为该元素是根节点...
谢谢!
亚历山大·哈辛托
与其依赖 <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]
,然后在 select 从 key1
跳转到 report
元素到 select 是 @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>
我有以下 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>
我想在 <element1>
元素之前添加一个名为 <valueIs>
的新元素,数据来自我用作 [=18] 的第二个 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
我是使用,
有什么方法可以在 <element1>
文件之前专门创建 <valueIs>
文件吗?我需要将 <valueIs>
元素保留在 <report>
元素内,因为该元素是根节点...
谢谢!
亚历山大·哈辛托
与其依赖 <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]
,然后在 select 从 key1
跳转到 report
元素到 select 是 @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>