我需要有关XSLT的帮助...
我有以下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>
<![CDATA[]]>
</element1>
<element2 name="secondElement"/>
<head>
<hText x="10" y="20">
<textVal>TEXT 1</textVal>
</hText>
<hText x="10" y="30">
<textVal>TEXT 2</textVal>
</hText>
<hText x="10" y="40">
<textVal>TEXT 3</textVal>
</hText>
</head>
<body/>
</report>
我正在尝试使用以下XSLT样式表对其进行转换:
<?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"
xmlns="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 forCDATA="THIS IS THE VALUE FOR CDATA 1">FIRST DATA 1</value>
<value forCDATA="THIS IS THE VALUE FOR CDATA 1">FIRST DATA 2</value>
<value forCDATA="THIS IS THE VALUE FOR CDATA 1">FIRST DATA 3</value>
</elemRep>
<elemRep tmpID="2" name="SecondTemplate">
<value forCDATA="THIS IS THE VALUE FOR CDATA 2">SECOND DATA</value>
</elemRep>
</elementReps>
</secondDoc>
</xsl:param>
<xsl:output indent="yes" cdata-section-elements="element1"/>
<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/*[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[1]" xpath-default-namespace=""/>
</valueIs>
<element1>
<xsl:value-of select="$rep/value[1]/@forCDATA" xpath-default-namespace=""/>
</element1>
</xsl:template>
<xsl:template match="element2">
<xsl:copy>
<xsl:copy-of select="@*"/>
<newChild>THIS IS THE NEW CHILD</newChild>
</xsl:copy>
</xsl:template>
<xsl:template match="report/body">
<xsl:variable name="temp2" select="key('key1', ancestor::report/@repName, $doc2)"/>
<xsl:variable name="rep2" select="key('key2', $temp2/@ID, $doc2)"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="$rep2/value" xpath-default-namespace="">
<xsl:variable name="vCount" select="count(preceding-sibling::value)+1"/>
<bText>
<xsl:attribute name="x">
<xsl:value-of select="/report/head/hText[$vCount]/@x"/>
</xsl:attribute>
<xsl:attribute name="y">
<xsl:value-of select="/report/head/hText[$vCount]/@y"/>
</xsl:attribute>
<textVal>
<xsl:value-of select="current()"/>
</textVal>
</bText>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如您所见,我正在使用第二个XML输入文档(doc2),该文档以<xsl:param>
的形式传递给XSLT。 XSLT样式表中不起作用的部分是最后一个<xsl:tempplate>
,<xsl:template match="report/body">
基本上,这是我想要的输出:
<?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 1</valueIs>
<element1><![CDATA[THIS IS THE VALUE FOR CDATA 1]]></element1>
<element2 name="secondElement">
<newChild>THIS IS THE NEW CHILD</newChild>
</element2>
<head>
<hText x="10" y="20">
<textVal>TEXT 1</textVal>
</hText>
<hText x="10" y="30">
<textVal>TEXT 2</textVal>
</hText>
<hText x="10" y="40">
<textVal>TEXT 3</textVal>
</hText>
</head>
<body>
<bText x="10" y="20">
<textVal>FIRST DATA 1</textVal>
</bText>
<bText x="10" y="30">
<textVal>FIRST DATA 2</textVal>
</bText>
<bText x="10" y="40">
<textVal>FIRST DATA 3</textVal>
</bText>
</body>
</report>
但这是我真正得到的输出:
<?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 1</valueIs>
<element1><![CDATA[THIS IS THE VALUE FOR CDATA 1]]></element1>
<element2 name="secondElement">
<newChild>THIS IS THE NEW CHILD</newChild>
</element2>
<head>
<hText x="10" y="20">
<textVal>TEXT 1</textVal>
</hText>
<hText x="10" y="30">
<textVal>TEXT 2</textVal>
</hText>
<hText x="10" y="40">
<textVal>TEXT 3</textVal>
</hText>
</head>
<body>
<bText x="" y="">
<textVal>FIRST DATA 1</textVal>
</bText>
<bText x="" y="">
<textVal>FIRST DATA 2</textVal>
</bText>
<bText x="" y="">
<textVal>FIRST DATA 3</textVal>
</bText>
</body>
</report>
如您所见,我无法从<xsl:value-of select="/report/head/hText[$vCount]/@x"/>
和<xsl:value-of select="/report/head/hText[$vCount]/@y"/>
获取值,无法将{{的x
和y
属性放入1}}个元素。
我认为这是因为在<bText>
中进入第二个XML输入文档(<xsl:for-each>
),然后在doc2
元素中尝试返回第一个XML输入文件。另外,我正在使用<xsl:value-of>
函数,因此可以确认我在第二个输入XML文档(current()
)的上下文中。
所以我需要做的是将名称空间改回doc2
或将上下文更改为第一个输入XML文档的上下文。
我该怎么做?我尝试做"http://jasperreports.sourceforge.net/jasperreports"
是因为我在<xsl:value-of select="/jsp:report/jsp:head/jsp:hText[$vCount]/@x"/>
元素中定义了该命名空间,但是它没有用。
XSLT FIDDLE AT: https://xsltfiddle.liberty-development.net/94hvTzn
谢谢!
Alexandre Jacinto
答案 0 :(得分:0)
将主输入文档存储在变量中,并确保将xpath默认名称空间切换回需要的位置:
<xsl:variable name="main-doc" select="/"/>
<xsl:for-each select="$rep2/value" xpath-default-namespace="">
<xsl:variable name="vCount" select="position()"/>
<bText xsl:xpath-default-namespace="http://jasperreports.sourceforge.net/jasperreports">
<xsl:attribute name="x">
<xsl:value-of select="$main-doc/report/head/hText[$vCount]/@x"/>
</xsl:attribute>
<xsl:attribute name="y">
<xsl:value-of select="$main-doc/report/head/hText[$vCount]/@y"/>
</xsl:attribute>
<textVal>
<xsl:value-of select="current()"/>
</textVal>
</bText>
</xsl:for-each>
https://xsltfiddle.liberty-development.net/94hvTzn/1
最后,在样式表中为主要输入元素声明名称空间前缀,然后在需要时使用它们来选择或匹配它们,然后在辅助输入文档中不使用前缀,可能会更容易。