删除节点中第二个分隔符之前的字符串

时间:2019-12-08 18:55:29

标签: xslt xslt-2.0

我想在第二个分隔符(|)之后删除节点中的字符串:

<A>
<B>First | Second | Third<B>
</A>
<A>
<B>Apple | Orange | Bananas | Kiwi<B>
</A>
<A>
<B>Example<B>
</A>

输出:

<A>
<B>First | Second<B>
</A>
<A>
<B>Apple | Orange<B>
</A>
<A>
<B>Example<B>
</A>

我的第一个想法是使用正则表达式:

<xsl:template match="B">
    <xsl:value-of select="replace(., '\|([^|]*)$', '')" />
</xsl:template>

...但是它并不是真的有效,也许有更好的方法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

要删除第一个分隔符|之后的其余字符串,您当然可以使用RegEx:

<xsl:template match="B">
  <xsl:copy>
    <xsl:value-of select="replace(., '(.*?)\s?\|.*?$', '$1')" />
  </xsl:copy>
</xsl:template>

其输出为

<root>
    <A>
        <B>First</B>
    </A>
    <A>
        <B>Apple</B>
    </A>
    <A>
        <B>Example</B>
    </A>
</root>

反之,如果您想获得问题中给出的输出,则可以使用上述RegEx的变体并使用它:

replace(., '(.*?)\|(.*?)\s?\|.*?$', '$1|$2')

其输出为

<root>
    <A>
        <B>First | Second</B>
    </A>
    <A>
        <B>Apple | Orange</B>
    </A>
    <A>
        <B>Example</B>
    </A>
</root>

答案 1 :(得分:1)

此转换:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

  <xsl:template match="B/text()">
    <xsl:value-of select="string-join(tokenize(., ' \| ')[position() lt 3], ' | ')"/>
  </xsl:template>
</xsl:stylesheet>

应用于提供的XML (片段,格式严重错误-现在已修复):

<t>
    <A>
        <B>First | Second | Third</B>
    </A>
    <A>
        <B>Apple | Orange | Bananas | Kiwi</B>
    </A>
    <A>
        <B>Example</B>
    </A>
</t>

产生想要的正确结果

<t>
   <A>
      <B>First | Second</B>
   </A>
   <A>
      <B>Apple | Orange</B>
   </A>
   <A>
      <B>Example</B>
   </A>
</t>

更新

问题中,说明与所提供的所需结果之间存在冲突。

以上解决方案会产生所需的结果。

如果真的只需要第一个令牌,则解决方案甚至更简单:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

  <xsl:template match="B/text()">
    <xsl:value-of select="tokenize(., ' \| ')[1]"/>
  </xsl:template>
</xsl:stylesheet>

将此转换应用于相同的XML文档(如上)时,将产生正确的(对于问题的解释)结果:

<t>
   <A>
      <B>First</B>
   </A>
   <A>
      <B>Apple</B>
   </A>
   <A>
      <B>Example</B>
   </A>
</t>