XSLT返回两个字符之间的字符串

时间:2016-02-17 17:10:34

标签: xslt between

我正在尝试返回XML表单中的部分字符串。 我想保留“描述”字段中括号之间的内容,并将括号外的内容移动到不同的字段:

源XML:

<Log>
   <Date>15-Nov-2014</Date>
   <TC>14:38:47:13</TC>
   <Description>Move this text (but keep this text here)</Description>
</Log>

期望的结果是:

<Log>
   <Date>15-Nov-2014</Date>
   <TC>14:38:47:13</TC>
   <Description>but keep this text here</Description>
   <MyOtherField>Move this text</MyOtherField> 
</Log>

我已经尝试使用substring-before“(”和“substring-after”)“函数在行中,输出几乎是正确的 - 但是问题是我的源XML表中的所有”描述“字段都没有括号中的文字,因此将被完全删除。

非常感谢任何协助。

谢谢

3 个答案:

答案 0 :(得分:4)

以这种方式尝试:

<xsl:template match="Description">
    <xsl:copy>
        <xsl:value-of select="substring-before(substring-after(., '('), ')')"/>
    </xsl:copy>
    <MyOtherField>
        <xsl:value-of select="substring-before(concat(., '('), '(')"/>
    </MyOtherField>
</xsl:template>

答案 1 :(得分:1)

由于您使用的是XSLT 2.0,因此可以使用xsl:analyze-string来获取parens之间的文本...

XML输入

<Log>
    <Date>15-Nov-2014</Date>
    <TC>14:38:47:13</TC>
    <Description>Move this text (but keep this text here)</Description>
</Log>

XSLT 2.0

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

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

  <xsl:template match="Description">
      <xsl:copy>
        <xsl:analyze-string select="." regex="\(([^)]+)\)">
          <xsl:matching-substring>
            <xsl:value-of select="regex-group(1)"/>
          </xsl:matching-substring>
        </xsl:analyze-string>
      </xsl:copy>
      <MyOtherField>
        <xsl:value-of select="normalize-space(string-join((substring-before(concat(.,'('),'('),
          substring-after(.,')')),' '))"/>
      </MyOtherField>      
  </xsl:template>

</xsl:stylesheet>

XML输出

<Log>
   <Date>15-Nov-2014</Date>
   <TC>14:38:47:13</TC>
   <Description>but keep this text here</Description>
   <MyOtherField>Move this text</MyOtherField>
</Log>

此处它已集成到您现有的代码中:http://xsltransform.net/pPzifq1/1

答案 2 :(得分:0)

我能够使用以下模板实现此目的:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

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

    <xsl:template match="Description[contains(text(), '(')]">
        <Description>
            <xsl:value-of select="substring-before(substring-after(., ' ('), ')')" />
        </Description>
        <MyOtherField>
            <xsl:value-of select="substring-before(., ' (')" />
        </MyOtherField>
    </xsl:template>
</xsl:transform>

请注意,如果您有多个() s,它可能无法正常工作。我们的想法是匹配任何包含Description的{​​{1}}标记,然后使用子字符串逻辑。

http://xsltransform.net/gWvjQfU