【问题标题】:XSLT - Remove specific value from attribute but keep other valuesXSLT - 从属性中删除特定值但保留其他值
【发布时间】:2016-08-26 09:47:37
【问题描述】:

我有以下 XML 输入:

<table>
    <tbody>
        <tr>
            <td style="width: 10px; margin-left: 10px;">td text</td>
            <td style="color: red; width: 25px; text-align: center; margin-left: 10px;">
                <span>span text</span>
            </td>
        </tr> 
    </tbody>
</table>

请注意,我在同一个文档中有其他节点不应该被触及。

我想从元素中删除某些属性值(在本例中是从 td)。 假设我想删除样式属性中的宽度值。 我不知道在样式属性中设置宽度值的位置,它可能在任何地方。 td 中的跨度并不重要(输入中包含此元素和其他一些元素)。

我希望输出是这样的:

<table>
    <tbody>
        <tr>
            <td style="margin-left: 10px;">td text</td>
            <td style="color: red; text-align: center; margin-left: 10px;">
                <span>span text</span>
            </td>
        </tr> 
    </tbody>
</table>

我更喜欢使用 XSLT1,我还没有使用 replace() 函数(但也许我做错了什么)。

我尝试使用此 XSLT:

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

<xsl:template match="td/@style">
        <xsl:attribute name="style">
            <xsl:value-of select="replace(., 'width:.[[:digit:]]+px;', '')" />
        </xsl:attribute>
    <xsl:apply-templates select="node()" /> 
</xsl:template> 

我仍然是 XSLT 的初学者,上面的这个不起作用,我在这里没有找到解决方案。 另外,我不知道宽度值,所以我需要用正则表达式替换该值(我使用了“width:.[[:digit:]]+px;”)或其他东西。 是否有更简单的方法可以替换每个特定值?所以我也可以删除 text-align 而不必考虑新的正则表达式?

我真的希望你能帮助我解决这个(当然很容易)的问题。 提前谢谢!

【问题讨论】:

  • replace 是 XSLT/XPath 2.0,所以我不确定你为什么说“我更喜欢使用 XSLT1”。至于一般解决方案,我认为您需要先实现 CSS 解析器或转换来处理 CSS 样式属性值。所以我认为这不是一个容易解决的问题,例如 CSS width 值不限于 px 单元。
  • "上面的这个不起作用" 这是一个无用的描述。您应该报告确切的结果并逐字复制收到的任何错误消息。

标签: regex xml xslt


【解决方案1】:

假设我想删除样式属性中的宽度值。一世 不知道在样式属性中设置宽度值的位置,它 可以在任何地方。

试试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="td/@style[contains(., 'width:')]">
    <xsl:attribute name="style">
        <xsl:value-of select="substring-before(., 'width:')" />
        <xsl:value-of select="substring-after(substring-after(., 'width:'), ';')" />
    </xsl:attribute>
</xsl:template> 

</xsl:stylesheet>

注意

我想从一个元素中删除某些属性值(在这个 td 的案例)。

实际上,您想要的是从style属性中删除某些属性。以上将适用于删除 single 属性;如果要删除多个,则必须使用递归模板来执行此操作。


补充:

如果样式包含border-width:1px 会出现问题 这变成border-

是的,这可能是个问题。一个可能的解决方案是:

<xsl:template match="td/@style">
    <xsl:variable name="style" select="concat(' ', .)" />
    <xsl:choose>
        <xsl:when test="contains($style, ' width:')">
            <xsl:attribute name="style">
                <xsl:value-of select="substring-before($style, ' width:')" />
                <xsl:value-of select="substring-after(substring-after($style, ' width:'), ';')" />
            </xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template> 

但是,这假定源文档中的 ; 分隔符后始终跟一个空格(如给定示例中所示)。否则会变得更复杂。

【讨论】:

  • 如果width 出现在style 属性的最后,则不必以分号结束。
  • 如果样式中包含border-width:1px 会不会有问题,因为这变成了border-
  • @TimC 是的,那是个问题。我已经为我的答案添加了一个可能的解决方案。
【解决方案2】:

假设您使用的是 XSLT 2.0(因为 replace 在 1.0 中不受支持),您可以使用 \d 匹配正则表达式中的数字,因此您可以这样编写模式:

<xsl:value-of select="replace(., '( | $)width:\s*\d*px;?', '')" />

注意\s* 用于匹配零个或多个空格字符,因此允许使用width:10pxwidth: 10px。也不是( | $) 用于确保width 之前的空格(或者如果它在开头),这样border-width 之类的属性就不会匹配。

如果您想处理px 以外的单位,您可以这样做...

<xsl:value-of select="replace(., '( | $)width:[^;]+;?', '')" />

http://www.xml.com/pub/a/2003/06/04/tr.html阅读正则表达式。

【讨论】:

  • 谢谢,但我认为我的处理器无法使用 replace() 函数,因为我在检查“funcall(replace, [step("self", -1), literal-expr(width:\s*\d*px;), literal-expr()])".'" 这是我的声明:w3.org/1999/XSL/Transform" version="2.0" > 是我的处理器导致了这个问题吗?如果是这样,我想我需要一个 XSLT1.0 模板 :-(
  • 听起来您使用的是 XSLT 1.0。请参阅stackoverflow.com/questions/25244370/… 以了解您使用的版本(答案适用于任何地方,而不仅仅是 solr)。
猜你喜欢
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2013-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
相关资源
最近更新 更多