条件在不应该出现的地方被调用

Condition getting getting called where it is not supposed to be

我有以下 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

谢谢

查看当前的 XSLT,当您应用正则表达式(使用分析字符串)时,您位于 para 元素上,而不是 content-style,因此 select="." 将获取整个 para 元素的字符串值,而不仅仅是第一个节点。

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

<xsl:analyze-string select="content-style[1]" regex="(\w+)/(\w+)/(\w+)">

在您当前的模板apply-templates中,此apply-templates也存在问题

 <xsl:apply-templates select="child::node()[not(self::content-style[1]/text())]"/>

我认为你想要做的是 select 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+)')]">

由于它有一个条件,它会比单独匹配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> 

请注意,您可能需要向 XSLT 添加一个 strip-space 元素,否则第一个 content-style 之前的任何白色 space 也将算作正确的节点。

<xsl:strip-space elements="*" />