英文:
Nested span tag class not applied in xsl xml transformation
问题
我想确保您想要的部分是正确的,以下是输出HTML中的一部分,其中第4行数据已被更正以显示为"book 4 .......",而不是"book 4 <span class="Dots"/>"。
<tr>
<td> book 4 .......</td>
<td>1004</td>
<tr>
请让我知道是否需要更多帮助。
英文:
I am new to xml and XSLT transformation. My data is in xml and is being transferred to html using XSLT. I am using java program to transform. I have a made a simple xml and XSL to show the problem I am facing. The xml has the data for books. Each book's title and location is being displayed inside a table's td. There is a <?del_mark> tag inside the xml. This tag means, that the content specified in the data attribute of this tag needs to be enclosed inside a strike out and a P tag.
<?del-mark data="<tr><td>book 5 <span class="Dots"/></td><td>1005</td></tr>" />
In the stylesheet there is a template to handle the processing instruction (del_mark)and it takes the data attribute's value and replaces it inside a p and strike through tag. It is working fine, but in the final html, it is not replacing the <span class="Dots"/>
with .... for the processing instruction template.
My problem is: There is a template for span tag which converts the span to dots using <span class="Dots"/>
. This template is not getting used and the tag appear as is <span class="Dots"/>instead of dots as described in the template.
I have a java program which reads the sample xml and checks for the processing tag <?del_mark> and reads the data part of it and converts all the < and " to < and ". Then, this intermediate xml is used to as input xml for the transformation. The intermediate xml is also given below.
Please let me know if you need more info.
SAMPLE XML
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"?>
<books>
<book>
<title>Book 1</title>
<location>1000</location>
</book>
<book>
<title>Book 2<span class="Dots"/>
</title>
<location>1002</location>
</book>
<book>
<title>Book 3</title>
<location>1003</location>
</book>
<?del_mark data=&quot;&lt;tr style=&quot;keep-with-next.within-page:always;&quot;>
&lt;td width=&quot;280&quot;>
&lt;p class=&quot;HangingIndent&quot;>Book&lt;span class=&quot;Dots&quot;/>
&lt;/strike>
&lt;/p>
&lt;div style=&quot;margin:0 0 1em 0;&quot;>&lt;/div>
&lt;/td>
&lt;td align=&quot;center&quot; valign=&quot;bottom&quot; width=&quot;136&quot;>1004&lt;/td>
&lt;/tr>&quot;?>
<book>
<title>Book 5</title>
<location>1005</location>
</book>
</books>
** SAMPLE XSL**
<?xml version="1.0" standalone="yes"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:math="java.lang.Math">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="/">
<html>
<head>
<title>Books</title>
</head>
<body>
<p> This a sample xml/xsl example<span class="Dots"/>
</p>
<table width="100%" border="1">
<THEAD>
<TR>
<TD width="35%">
<B>Title</B>
</TD>
<TD width="15%">
<B>Location</B>
</TD>
</TR>
</THEAD>
<TBODY>
<xsl:for-each select="books/book|books/processing-instruction()">
<tr>
<xsl:apply-templates select="."/>
</tr>
</xsl:for-each>
</TBODY>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="title">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
<xsl:template match="location">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
<xsl:template match="xhtml:span | span">
<xsl:if test="@class='Spaces'">
_________
</xsl:if>
<xsl:if test="@class='Dots'">
..........
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="processing-instruction('del_mark')">
<xsl:text disable-output-escaping="yes"><![CDATA[<font color="yellow"><strike>]]></xsl:text>
<xsl:variable name="dval" select="substring-after(current(), 'data=')"/>
<xsl:variable name="v1">
<xsl:value-of select="$dval" disable-output-escaping="yes"/>
</xsl:variable>
<xsl:value-of select="substring($v1, 2, string-length($v1) - 2)" disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes"><![CDATA[</strike></font>]]></xsl:text>
</xsl:template>
</xsl:stylesheet>
** INTERMEDIATE XML **
<?xml-stylesheet type="text/xsl"?><books>
<book>
<title>Book 1</title>
<location>1000</location>
</book>
<book>
<title>Book 2<span class="Dots"/>
</title>
<location>1002</location>
</book>
<book>
<title>Book 3</title>
<location>1003</location>
</book>
<?del_mark <p style="display:inline;">data="<tr style="keep-with-next.within-page:always;">
<td width="280">
<p class="HangingIndent">Book<span class="Dots"/>
</strike>
</strike></p><div style="margin:0 0 1em 0;"></div>
<div style="margin:0 0 1em 0;"></div>
</td>
<td align="center" valign="bottom" width="136">1004</td>
</tr>"?>
<book>
<title>Book 5</title>
<location>1005</location>
</book>
</books>
HTML Output
<html xmlns:math="java.lang.Math" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns="http://www.w3.org/1999/xhtml" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<head>
<title>Books</title>
</head>
<body>
<p> This a sample xml/xsl example<span class="Dots"></span></p>
<table width="100%" border="1">
<THEAD>
<TR>
<TD width="35%"><B>Title</B></TD>
<TD width="15%"><B>Location</B></TD>
</TR>
</THEAD>
<TBODY>
<tr>
<td>Book 1</td>
<td>1000</td>
</tr>
<tr>
<td>Book 2
</td>
<td>1002</td>
</tr>
<tr>
<td>Book 3</td>
<td>1003</td>
</tr>
<tr><font color="yellow"><strike><tr style="keep-with-next.within-page:always;">
<td width="280">
<p class="HangingIndent">Book<span class="Dots"/>
</strike>
</strike></p><div style="margin:0 0 1em 0;"></div>
<div style="margin:0 0 1em 0;"></div>
</td>
<td align="center" valign="bottom" width="136">1004</td>
</tr></strike></font>
</tr>
<tr>
<td>Book 5</td>
<td>1005</td>
</tr>
</TBODY>
</table>
</body>
</html>
IN the output html, I want the row 4 data to be shown as book 4... instead of book 4 <span class="Dots"/>
.
<tr>
<td> book 4 .......</td>
<td>1004</td>
<tr>
Thanks.
答案1
得分: 1
span
节点的模板首先没有被应用,因为你没有尝试使用 xsl:apply-templates
应用它,其次因为你的文档实际上没有 span
节点。你的文档中只有一些数据,如果它被解析为XML,那么它们才会成为 span
节点。
在现代版本的XSLT中,有一个 parse-xml()
函数,允许你将处理指令中的词法XML转换为节点树,然后可以像通常一样处理它们(例如使用 xsl:apply-templates
)。实现较早版本XSLT的处理器可能会有一个执行相同操作的扩展函数,或者它们可能允许你自己编写扩展函数(例如调用Java)。
在Saxon中还有一个扩展函数 get-pseudo-attributes()
,允许你提取处理指令的 "data" 伪属性。
所以:
-
提取处理指令数据的内容,就像你现在所做的那样:
<xsl:variable name="dval" select="substring-after(current(), 'data=')"/>
并去掉前导和尾随引号。
-
或者使用
saxon:get-pseudo-attribute('data')
-
对结果调用
parse-xml()
-
对结果调用
apply-templates
所以它可以简单地是这样的:
<xsl:template match="processing-instruction('del_mark')">
<font color="yellow">
<strike>
<xsl:apply-templates
select="parse-xml(saxon:get-pseudo-attribute('data'))"
xmlns:saxon="http://saxon.sf.net/"/>
</strike>
</font>
</xsl:template>
为了增加一些额外的模块化,我会将 span
的模板规则放在一个单独的模式中:
<xsl:mode name="nested-xml" on-no-match="shallow-copy"/>
<xsl:template match="span" mode="nested-xml">
...
</xsl:template>
然后:
<xsl:apply-templates
select="parse-xml(saxon:get-pseudo-attribute('data'))"
mode="nested-xml"
xmlns:saxon="http://saxon.sf.net/"/>
英文:
The template for the span
node isn't being applied firstly because you make no attempt to apply it using xsl:apply-templates
, and secondly because there is in fact no span
node in your document. There's only some data that would be turned into a span
node if it were parsed as XML.
In modern versions of XSLT there is a parse-xml()
function that allows you to turn the lexical XML in your processing instruction into a tree of nodes, which can then be processed in the normal way (for example using xsl:apply-templates
). Processors implementing earlier versions of XSLT may have an extension function that does the same thing, or they may allow you to write your own (for example by calling out to Java).
In Saxon there is also an extension function get-pseudo-attributes()
that allows you to extract the "data" pseudo-attribute of your PI.
So:
-
Extract the contents of the PI data as you do now:
<xsl:variable name="dval" select="substring-after(current(), 'data=')"/>
and strip off the leading and trailing quotes.
-
Alternatively, use
saxon:get-pseudo-attribute('data')
-
Call
parse-xml()
on the result -
Call `apply-templates on the result.
So it could simply be:
<xsl:template match="processing-instruction('del_mark')">
<font color="yellow">
<strike>
<xsl:apply-templates
select="parse-xml(saxon:get-pseudo-attribute('data')"
xmlns:saxon="http://saxon.sf.net/"/>
</strike>
</font>
</xsl:template>
For a bit of extra modularity, I would put the template rule for span
in a separate mode:
<xsl:mode name="nested-xml" on-no-match="shallow-copy"/>
<xsl:template match="span" mode="nested-xml">
...
</xsl:template>
and then
<xsl:apply-templates
select="parse-xml(saxon:get-pseudo-attribute('data')"
mode="nested-xml"
xmlns:saxon="http://saxon.sf.net/"/>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论