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

Remove string before second separator in a node

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

<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>

...但它并没有真正起作用,也许有更好的方法来做到这一点?

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

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

它的输出是

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

另一方面,如果你想得到你在问题中给出的输出,你可以使用上述 RegEx 的变体并使用这个:

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

它的输出是

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

这次改造:

<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>

更新:

问题中的描述与提供的想要的结果有冲突。

上面的解决方案产生了所提供的想要的结果。

如果真的只需要第一个token,那么解决方法就更简单了:

<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>