我在子节点之间有一个循环 我可以说一句话:阻止比另一个词:
<mynode>
Hi ok
<fo:block>
hi ok fo block
< /fo:block>
maybe another text node here...
</mynode>
我必须将<fo:block>
替换为<div>
,但我必须将文本保留在相同的位置(如果存在,可以在fo:block之前和之后)
我尝试这段代码但是(假设循环子(*)节点):
<xsl:for-each select="/mynode">
<xsl:if test="text()"><xsl:value-of select="text()"/></xsl:if>
<xsl:for-each select="child::*">
<!--for every child node of mynode-->
<xsl:choose>
<xsl:when test="normalize-space(local-name())
= normalize-space('block')">
<xsl:call-template name="fo-block">
<xsl:with-param .../>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:if test="text()"><xsl:value-of select="text()"/></xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
如果test = text()所以节点包含文本然后显示文本,否则我得到节点的名称并测试if是否为块:如果是,我调用特定模板,否则测试是否包含文本。
现在似乎工作..那么,我的范围可能是正确的选择/代码吗?
谢谢!
拉吉
答案 0 :(得分:0)
乍一看出现的问题包括:
你的内部for-each循环遍历child::*
,它将匹配每个元素子元素;它不会匹配任何其他子项(文本节点,注释,处理指令)。我认为你的意思是child::node()
。
您对块元素("normalize-space(local-name()) = normalize-space('block')"
)的测试是名称空间遗忘,因此它不必要地脆弱。对normalize-space()的调用是没有意义的,因为local-name()永远不会返回包含空格的任何字符串,并且文字字符串&#39; block&#39;不包含任何空格。
更短,更可靠的测试是test="self::fo:block"
。
你说
Seems to work for now..
如果您的测试显示此代码有效,那么您的测试并没有给您带来尽可能好的效果。
您描述的处理部分似乎相当于:将fo:block
元素更改为div
;让其他一切都一样。处理此类转换的最简单方法是编写身份转换,然后添加更具体的规则来捕获需要更改的内容。例如:
<xsl:template match="fo:block">
<div>
<xsl:apply-templates select="@*|node()"/>
</div>
</xsl:template>
<!--* other non-identity processing goes here ... *-->
<!--* What we don't have specific rules for gets handled
* by the following template and the default templates,
* which together perform an identity transform. *-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:0)
M。,
您的架构和响应非常有用
我增加了我的fo:block translation的复杂性:如果im在表中(在fo:cell parent中)我认为属性被html替换我使用div,否则(任何地方)p ..所以,我做了这些修改,希望你同意:
<xsl:template match="fo:block">
<xsl:choose>
<xsl:when test="parent::fo:table-cell">
<div>
<xsl:apply-templates select="node()"/>
</div>
</xsl:when>
<xsl:otherwise>
<xsl:if test="@space-before"> <!-- distance before is rep. by br -->
<xsl:call-template name="count-br"> <!-- write a br tag for each unit -->
<xsl:with-param name="howmuch"><xsl:value-of select="substring-before(normalize-space(@space-before),'cm')"/></xsl:with-param>
</xsl:call-template>
</xsl:if>
<p>
<xsl:if test="@font-size">
<xsl:attribute name="font-size"><xsl:value-of select="@font-size"/></xsl:attribute>
</xsl:if>
<xsl:if test="@text-align">
<xsl:attribute name="text-align"><xsl:value-of select="@text-align"/></xsl:attribute>
</xsl:if>
<xsl:if test="@font-family">
<xsl:attribute name="font-family"><xsl:value-of select="@font-family"/></xsl:attribute>
</xsl:if>
<xsl:apply-templates select="node()"/>
</p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>