条件在不应该出现的地方被调用
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>—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>     </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> 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="*" />
我有以下 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>—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>     </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> 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="*" />