2017-02-24 48 views
0

我有一个xml文件,我通过xsl处理成一个csv文件。它工作得非常好,除了。 源xml包含其值为分隔字符串的节点 - 分隔符是冒号。 的分隔字符串中的章节中可能包含一个冒号 我需要一个\xsl替换匹配':'但不是':'

即我的XML来代替分隔符是这样的:

<docnode> 
    <group> 
    <parent> 
     <child>value1a:value2:value3 part1: part2</child> 
     <other>some other stuff I don't care about</other> 
    </parent> 
    <group> 
    </group> 
    <parent> 
     <child>value1b:value2:value3 part1: part2</child> 
     <other>some other stuff I don't care about</other> 
    </parent> 
    </group> 
</docnode> 

我XSL目前拥有:

<xsl:for-each select="group"><xsl:value-of select="translate(parent/child,':','\')"/></xsl:for-each> 

此输出

value1a\value2\value3 part1\ part2 
value1b\value2\value3 part1\ part2 

我需要:

value1a\value2\value3 part1: part2 
value1b\value2\value3 part1: part2 

我知道这是坚果,但我无法控制格式。

我想我应该能够使用正则表达式:[\ S],将匹配不具有空间冒号后it.e

我无法找到任何的正则表达式:翻译(仅适用于正则表达式:更换) 如:

当我尝试其中的任意一种选择,XSL给我什么

帮助?? !!

+0

哪些XSLT处理器您使用的? –

+0

https://www.microsoft.com/en-ca/download/details.aspx?id=21714 – David

回答

0

假设你正在使用XSLT 1.0处理器,不带扩展功能,你将不得不做这样的事情:

<xsl:template match="/docnode"> 
    <xsl:for-each select="group"> 
     <xsl:call-template name="replace"> 
      <xsl:with-param name="string" select="parent/child"/> 
     </xsl:call-template> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template name="replace"> 
    <xsl:param name="string"/> 
    <xsl:choose> 
     <xsl:when test="contains($string, ':')"> 
      <xsl:value-of select="substring-before($string, ':')"/> 
      <xsl:choose> 
       <xsl:when test="starts-with(substring-after($string, ':'), ' ')">:</xsl:when> 
       <xsl:otherwise>\</xsl:otherwise> 
      </xsl:choose> 
      <xsl:call-template name="replace"> 
       <xsl:with-param name="string" select="substring-after($string, ':')"/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$string"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
+0

这真棒,我真的很喜欢他们的方式,你做到了。 当我通过我的文件运行xslt时,我只得到1条记录,而不是2条记录。 '<?xml version =“1.0”?> value1a \ value2 \ value3 part1:part2' 有什么想法? – David

+0

无法获得此格式的工作,将在下面回复... – David

+0

@David我相信您的示例输入中存在错误。在第一个''之后,您有''而不是''。所以只有一个组,它包含一个空的子组。比较http://xsltransform.net/jz1PuQ5反对http://xsltransform.net/jz1PuQ5/1 –

0

起初,我想过负先行

<xsl:value-of select="replace(., ':(?!\\)', '\\')"/> 

但似乎XSLT不支持此功能。

而是使用:

<xsl:value-of select="replace(., ':([^\\ ])', '\\$1')"/> 

这意味着:

  • 找到:
  • 后跟一个空格[^\\ ]
  • 拍摄这组(...)以外的东西,
  • 更换这与:
    • 反斜杠\\
    • 和所捕获的组$1

注意,在正则表达式模式反斜杠字符必须加倍。

我使用Saxon引擎和XSLT版本2.0,通过在线XSLT验证程序测试了此解决方案。

整个模板是:

<xsl:template match="child"> 
    <xsl:copy> 
    <xsl:value-of select="replace(., ':([^\\ ])', '\\$1')"/> 
    </xsl:copy> 
</xsl:template> 
+0

对于“其次是一个空间以外的东西'[^ \\]'”我看不到什么加倍的反斜杠是在那里做。这意味着“空间或反斜线以外的东西”。当然你只是想''^''。 –

+0

迈克尔,你是对的。空间的引用是不需要的。 –