在不应该被调用的地方被调用

时间:2015-02-02 08:25:46

标签: regex xslt xpath xslt-2.0

我有以下的XML。

<?xml version="1.0" encoding="UTF-8"?>
<body>
  <para><content-style font-style="bold">18/8/7</content-style> <content-style font-style="italic">(2) Here is the content</content-style>&#x2014;Contributory negligence  accident 
<content-style font-style="italic">second v/w datav. </content-style> </para>
</body>

以及下面的XSL。

       <?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="/">
      <hmtl>
        <head>
          <title>New Version!</title>
        </head>
        <xsl:apply-templates/>
      </hmtl>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="para[node()[position() = 1 and self::content-style[matches(., '(\w+)/(\w+)')]]]">
        <div class="para">
                    <xsl:analyze-string select="." regex="(\w+)/(\w+)/(\w+)">
                        <xsl:matching-substring>
                            <a name="{concat('P',regex-group(1),'-',regex-group(2),'-',regex-group(3))}"/>
                            <span class="phrase">
                                <xsl:value-of select="."/>
                            </span>
                        </xsl:matching-substring>
                        <xsl:non-matching-substring>
                            <xsl:analyze-string select="." regex="(\w+)/(\w+)">
                                <xsl:matching-substring>
                                    <a name="{concat('P',regex-group(1),'-',regex-group(2))}"/>
                                    <span class="phrase">
                                        <xsl:value-of select="."/>
                                    </span>
                                    <xsl:text>&#160;&#160;&#160;&#160;&#160;</xsl:text>
                                </xsl:matching-substring>
                                <xsl:non-matching-substring>
                                    <xsl:value-of select="."/>
                                </xsl:non-matching-substring>
                            </xsl:analyze-string>
                        </xsl:non-matching-substring>
                    </xsl:analyze-string>
            <xsl:apply-templates select="child::node()[not(self::content-style[1]/text())]"/>
        </div>
    </xsl:template>

  <xsl:template match="content-style">
        <xsl:choose>
            <xsl:when test="./@format">
                <span class="format-{@format}">
                    <xsl:apply-templates/>
                </span>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="fontStyle">
                    <xsl:value-of select="concat('font-style-',@font-style)"/>
                </xsl:variable>
                <span class="{$fontStyle}">
                    <xsl:apply-templates/>
                </span>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>  

</xsl:transform> 

这里我遇到的问题是正在两个content-styles上调用正则表达式,但是我希望只在没有先前数据(文本或节点)的content-style上调用它,即仅在<para><content-style>之类的节点上,而不是像<para>(text/node)<content-style>那样。

当前O / p:

<div class="para"><a name="P18-8-7"></a><span class="phrase">18/8/7</span> (2) Here is the content—Contributory negligence  accident 
         second <a name="Pv-w"></a><span class="phrase">v/w</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datav.   —Contributory negligence  accident 

      </div>

预期的O / P

  <div class="para"><a name="P18-8-7"></a><span class="phrase">18/8/7</span> (2) Here is the content—Contributory negligence  accident 
             second <span class="font-style-italic">second v/w datav.</span>
          </div>

请让我知道我哪里出错了,我该如何解决这个问题。 Working Demo

由于

1 个答案:

答案 0 :(得分:1)

查看当前的XSLT,在您应用正则表达式时(使用analyze-string),您将位于para元素上,而不是content-style,这样做{{1} }将获取整个select="."元素的字符串值,而不仅仅是第一个节点。

您可能需要做的是将其更改为此,因此它只会分析第一个para(您知道它是模板匹配条件中的第一个节点)

content-string

您当前模板中的<xsl:analyze-string select="content-style[1]" regex="(\w+)/(\w+)/(\w+)"> 也存在问题

apply-templates

我认为您要做的是选择 <xsl:apply-templates select="child::node()[not(self::content-style[1]/text())]"/> 的子节点,而不是第一个para。如果是这样,您应该将其更改为

child-element

这可能会为您提供所需。

或者,您可以将匹配 <xsl:apply-templates select="child::node()[position() > 1]"/> 的当前模板更改为与第一个para匹配的模板:

content-style

由于它有条件,因此它的优先级高于匹配<xsl:template match="content-style[not(preceding-sibling::node())][matches(., '(\w+)/(\w+)')]"> 的模板。

作为一个非常简单的示例,请尝试将此XSLT作为基础

content-style

注意,您可能需要向XSLT添加<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="xml" indent="yes" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="content-style[not(preceding-sibling::node())][matches(., '(\w+)/(\w+)')]"> <content-style class="first"> <!-- Regex here! --> <xsl:apply-templates /> </content-style> </xsl:template> <xsl:template match="content-style"> <content-style class="other"> <!-- Other --> <xsl:apply-templates /> </content-style> </xsl:template> </xsl:stylesheet> 元素,否则在第一个strip-space之前的任何空格也将被视为正确的节点。

content-style