XSLT1.0:是否可以从字符串中删除括号内的内容



我希望删除括号内的内容,只显示原始内容。这是我的XML:

<?xml version="1.0" encoding="utf-16"?>
<Lite Version="0.0.0">
    <LogEventCollection>
        <LogEvent Type="SONG" ScheduledTime="2015-10-15T22:00:00.0004997Z" StartTime="2015-10-15T22:00:00.0004997Z" StartTimeLocal="10/15/2015 4:00:00 PM" Chain="SEGUE" Status="CURRENT" Duration="02:40">
        <Asset Type="SONG" AssetTypeName="Song" Title="Title (Extra Info)" Artist1="ArtistHere" ThirdPartyId="SongA" TotalLength="160"/>
        <NotesCollection>
            <Note Title="Note 1" Script="Note 1' Script"/>
            <Note Title="Note 2"/>
        </NotesCollection>
        </LogEvent>
    </LogEventCollection>
</Lite>

我希望在括号内不显示额外信息的情况下显示"Title"。我尝试过使用translate,但我不确定如何选择里面的信息。这是我当前的XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="newline">
    <xsl:text>&#13;</xsl:text>
</xsl:variable>
<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="LogEventCollection">
    <xsl:variable name="TITLE" select="LogEvent/Asset/@Title"/>
    <xsl:for-each select="LogEvent">
        <xsl:choose>
            <xsl:when test="@Type='SONG'">
                <xsl:value-of select="translate($TITLE, '(*)','')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text/>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:value-of select="$newline"/>
    </xsl:for-each>
    <xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

你可以想象,这只是去掉括号,而不是里面的内容。当前显示的Title Extra Info希望仅显示Title

这里有一个短两倍的解决方案(当假设每个@Title属性最多存在一对左->右括号时,可以正确工作:)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>
  <xsl:template match="/*">
    <xsl:apply-templates select="*/LogEvent[@Type='SONG']/Asset[@Type='SONG']/@Title"/>
  </xsl:template>
  <xsl:template match="@Title">
    <xsl:variable name="vLeft" select="substring-before(concat(.,'('), '(')"/>
    <xsl:variable name="vRight" 
         select="substring-after(substring-after(., concat($vLeft, '(')), ')')"/>
    <xsl:value-of select="concat($vLeft, $vRight, '&#xA;')"/>
  </xsl:template>
</xsl:stylesheet>

当应用于此源XML文档时(提供的文档扩展到涵盖所有可能的情况):

<Lite Version="0.0.0">
    <LogEventCollection>
        <LogEvent Type="SONG" 
        ScheduledTime="2015-10-15T22:00:00.0004997Z" 
        StartTime="2015-10-15T22:00:00.0004997Z" 
        StartTimeLocal="10/15/2015 4:00:00 PM" 
        Chain="SEGUE" 
        Status="CURRENT" 
        Duration="02:40">
            <Asset Type="SONG" 
            AssetTypeName="Song" 
            Title="Title1 Left (Extra Info)" 
            Artist1="ArtistHere"
            ThirdPartyId="SongA"
            TotalLength="160"/>
            <NotesCollection>
                <Note Title="Note 1" Script="Note 1' Script"/>
                <Note Title="Note 2"/>
            </NotesCollection>
        </LogEvent>
        <LogEvent Type="SONG" 
        ScheduledTime="2015-10-15T22:00:00.0004997Z" 
        StartTime="2015-10-15T22:00:00.0004997Z" 
        StartTimeLocal="10/15/2015 4:00:00 PM" 
        Chain="SEGUE" 
        Status="CURRENT" 
        Duration="02:40">
            <Asset Type="SONG" 
            AssetTypeName="Song" 
            Title="Title2 (Extra Info) surround" 
            Artist1="ArtistHere"
            ThirdPartyId="SongA"
            TotalLength="160"/>
            <NotesCollection>
                <Note Title="Note 1" Script="Note 1' Script"/>
                <Note Title="Note 2"/>
            </NotesCollection>
        </LogEvent>
        <LogEvent Type="SONG" 
        ScheduledTime="2015-10-15T22:00:00.0004997Z" 
        StartTime="2015-10-15T22:00:00.0004997Z" 
        StartTimeLocal="10/15/2015 4:00:00 PM" 
        Chain="SEGUE" 
        Status="CURRENT" 
        Duration="02:40">
            <Asset Type="SONG" 
            AssetTypeName="Song" 
            Title="(Extra Info)Title3 Right" 
            Artist1="ArtistHere"
            ThirdPartyId="SongA"
            TotalLength="160"/>
            <NotesCollection>
                <Note Title="Note 1" Script="Note 1' Script"/>
                <Note Title="Note 2"/>
            </NotesCollection>
        </LogEvent>
        <LogEvent Type="SONG" 
        ScheduledTime="2015-10-15T22:00:00.0004997Z" 
        StartTime="2015-10-15T22:00:00.0004997Z" 
        StartTimeLocal="10/15/2015 4:00:00 PM" 
        Chain="SEGUE" 
        Status="CURRENT" 
        Duration="02:40">
            <Asset Type="SONG" 
            AssetTypeName="Song" 
            Title="Title4 No brackets" 
            Artist1="ArtistHere"
            ThirdPartyId="SongA"
            TotalLength="160"/>
            <NotesCollection>
                <Note Title="Note 1" Script="Note 1' Script"/>
                <Note Title="Note 2"/>
            </NotesCollection>
        </LogEvent>
    </LogEventCollection>
</Lite>

生成所需的正确结果(适用于所有Title属性)

Title1 Left 
Title2  surround
Title3 Right
Title4 No brackets

尝试以下操作:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/Lite">
    <xsl:for-each select="LogEventCollection/LogEvent[@Type='SONG']">
        <xsl:variable name="TITLE" select="Asset/@Title"/>
        <xsl:choose>
            <xsl:when test="contains($TITLE, '(') and contains($TITLE, ')')">
                <xsl:value-of select="substring-before($TITLE, '(')"/>
                <xsl:value-of select="substring-after($TITLE, ')')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$TITLE"/>
            </xsl:otherwise>
        </xsl:choose>       
        <xsl:text>&#13;</xsl:text>
    </xsl:for-each> 
</xsl:template>
</xsl:stylesheet>

严格来说,应该测试一下右括号是否在左括号的之后,但是。。。

您可以尝试以下操作:

<xsl:value-of select="concat(substring-before( @Title,'(' ), substring-after( @Title,')' ) )" />

仅当右括号后有字符串时才需要substring-after()

更新(修复doe到完美的答案形式Dimitre Novatchev):

<xsl:value-of select="concat(
                     substring-before( concat( @Title, '(') ,'(' ), 
                     substring-after( @Title,')' ) )" />

最新更新