我需要删除这个xmlvia xslt中的文件路径
<?xml version="1.0" encoding="ISO-8859-1"?>
<InvoiceCapture>
<Invoice>
<CaptureDate>2014-02-19</CaptureDate>
<CaptureTime>14:04:07</CaptureTime>
<Company>bygg</Company>
<Type>0</Type>
<Supplier>11111111</Supplier>
<SupplierInvoiceNo>11111111</SupplierInvoiceNo>
<InvoiceDate>2013-12-30</InvoiceDate>
<DueDate>2014-01-29</DueDate>
<Reference1>11111111</Reference1>
<Reference2>11111111</Reference2>
<Currency>SEK</Currency>
<Amount>11111111</Amount>
<VatAmount>11111111</VatAmount>
<AlternativeID>20140219_bygg_2788</AlternativeID>
<ImageFile>\extsql1INVOICESm3Byggtest2KB16000.PNG \extsql1INVOICESm3Byggtest2KB16002.PNG \extsql1INVOICESm3Byggtest2KB16004.PNG \extsql1INVOICESm3Byggtest2KB16006.PNG \extsql1INVOICESm3Byggtest2KB16008.PNG</ImageFile>
<NoOfImages>5</NoOfImages>
<BatchPrefix/>
<BatchNo>2788</BatchNo>
<InvoiceLine/>
</Invoice>
</InvoiceCapture>
我需要的输出只是用空格分隔的图像名称:
<ImageFile>2JE04000.PNG 2JE04002.PNG 2JE04004.PNG 2JE04006.PNG 2JE04008.PNG</ImageFile>
我的建议是这个我称之为extract-substrings-between
的模板。它的优点是使用单个模板执行任务,不需要特定于此实际问题且更普遍有用的扩展。
其参数为:
-
string
:要处理的字符串。它默认为当前节点的值,并应用了normalize-space()
。 -
startCharacter
和endCharacter
:模板提取任何既不包含startCharacter
也不包含endCharacter
的子字符串,但紧跟在字符串的startCharacter
或开头,紧跟字符串的endCharacter
或结尾。startCharacter
和endCharacter
都默认为空格。 -
outputSeparator
:顾名思义,在输出时分隔提取的子字符串的字符串。默认也为空格。
样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:for-each select="InvoiceCapture/Invoice/ImageFile">
<xsl:copy>
<xsl:call-template name="extract-substrings-between">
<xsl:with-param name="startCharacter" select="''"/>
</xsl:call-template>
</xsl:copy>
</xsl:for-each>
</xsl:template>
<xsl:template name="extract-substrings-between">
<xsl:param name="string" select="normalize-space()"/>
<xsl:param name="startCharacter" select="' '"/>
<xsl:param name="endCharacter" select="' '"/>
<xsl:param name="outputSeparator" select="' '"/>
<xsl:variable name="currentToken"
select="substring-before(concat($string, $endCharacter), $endCharacter)"/>
<xsl:choose>
<xsl:when test="contains($currentToken, $startCharacter)">
<!-- We need to chip off more from the current token -->
<xsl:call-template name="extract-substrings-between">
<xsl:with-param name="string" select="substring-after($string, $startCharacter)"/>
<xsl:with-param name="startCharacter" select="$startCharacter"/>
<xsl:with-param name="endCharacter" select="$endCharacter"/>
<xsl:with-param name="outputSeparator" select="$outputSeparator"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- We've isolated what we want to return from the current token -->
<xsl:value-of select="$currentToken"/>
<xsl:variable name="remainingString" select="substring-after($string, ' ')"/>
<xsl:if test="$remainingString != ''">
<xsl:value-of select="$outputSeparator"/>
<xsl:call-template name="extract-substrings-between">
<xsl:with-param name="string" select="$remainingString"/>
<xsl:with-param name="startCharacter" select="$startCharacter"/>
<xsl:with-param name="endCharacter" select="$endCharacter"/>
<xsl:with-param name="outputSeparator" select="$outputSeparator"/>
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
输出:
<ImageFile>2KB16000.PNG 2KB16002.PNG 2KB16004.PNG 2KB16006.PNG 2KB16008.PNG</ImageFile>
您的预期输出不再与输入 XML 匹配。不过,下面是 XSLT 1.0 中的一个解决方案 - 正如我所说,这很困难。tokenize()
等函数在 XSLT 1.0 中不可用,并且不能将结果树片段用作本机节点集。我的解决方案使用 EXSLT 将结果树片段转换为节点集。
仅当文件路径相似且末尾包含"\test\"时,这才有效。
样式表
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="//ImageFile">
<xsl:copy>
<xsl:variable name="tokens">
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="exsl:node-set($tokens)/*">
<xsl:value-of select="substring-after(.,'test')"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="string" select="."/>
<xsl:param name="separator" select="' '"/>
<xsl:choose>
<xsl:when test="not(contains($string, $separator))">
<item>
<xsl:value-of select="normalize-space($string)"/>
</item>
</xsl:when>
<xsl:otherwise>
<item>
<xsl:value-of select="normalize-space(substring-before($string, $separator))"/>
</item>
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="substring-after($string, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
输出
<ImageFile>2KB16000.PNG 2KB16002.PNG 2KB16004.PNG 2KB16006.PNG 2KB16008.PNG </ImageFile>
假设路径确实由制表符 ( 	
) 字符分隔(很难从复制的示例中分辨出来),并且不假设除了分隔符之外的路径有任何内容,请尝试以下样式表:
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:template match="/">
<xsl:for-each select="InvoiceCapture/Invoice/ImageFile">
<xsl:copy>
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="."/>
</xsl:call-template>
</xsl:copy>
</xsl:for-each>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="string"/>
<xsl:param name="delimiter" select="'	'"/>
<xsl:choose>
<xsl:when test="contains($string, $delimiter)">
<xsl:call-template name="file-name">
<xsl:with-param name="path" select="substring-before($string, $delimiter)"/>
</xsl:call-template>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="substring-after($string, $delimiter)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="file-name">
<xsl:with-param name="path" select="$string"/>
<xsl:with-param name="last-token" select="true()"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="file-name">
<xsl:param name="path"/>
<xsl:param name="delimiter" select="''"/>
<xsl:param name="last-token"/>
<xsl:choose>
<xsl:when test="contains($path, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="file-name">
<xsl:with-param name="path" select="substring-after($path, $delimiter)" />
<xsl:with-param name="last-token" select="$last-token" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$path"/>
<xsl:if test="not($last-token)">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>