元素需要在xsl中拆分为两个元素

时间:2015-04-07 12:24:35

标签: xml xslt xslt-2.0

我有元素

<PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>`
在XSLT 2.0中我需要将它分成两个元素

<PredecessorActivityUID1>000005001302</PredecessorActivityUID1>
<PredecessorActivityUID2>0030</PredecessorActivityUID1>

分为两个不同的变量PredecessorActivityUID1,PredecessorActivityUID2

4 个答案:

答案 0 :(得分:1)

我刚试过子串功能。看看它是否有用。

<xsl:stylesheet version="1.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="PredecessorActivityUID" name="split">
  <xsl:param name="pText" select="." />

  <xsl:if test="$pText">
   <PredecessorActivityUID>
    <xsl:value-of select="substring-before(concat($pText, '-'), '-')" />
   </PredecessorActivityUID>

   <xsl:call-template name="split">
    <xsl:with-param name="pText" select="substring-after($pText, '-')" />
   </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

在此文件中:

<PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>

使用此样式表:

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

    <xsl:template match="/PredecessorActivityUID">
    <root>
      <xsl:variable name='uid1' select="substring-before(./text(), '-')"/>
      <xsl:variable name='uid2' select="substring-after(./text(), '-')"/>
      <PredecessorActivityUID1><xsl:value-of select='$uid1'/></PredecessorActivityUID1>
      <PredecessorActivityUID2><xsl:value-of select='$uid2'/></PredecessorActivityUID2>
    </root>
    </xsl:template>


</xsl:transform>

要获得此结果:

<root>
   <PredecessorActivityUID1>000005001302</PredecessorActivityUID1>
   <PredecessorActivityUID2>0030</PredecessorActivityUID2>
</root>

http://xsltransform.net/bdxtqn

这里不一定需要递归模板,特别是对于这样一个简单的要求。如果你不得不将字符串分成多个部分,这将是很好的。 tokenize()非常棒,并且会得到您的处理器的支持,但您的要求非常简单,以至于此代码可能更清晰(使用RegEx可能会对维护性造成过大杀伤)。

这适用于XSLT 1.0或2.0,不应要求任何扩展或特定于处理器的特殊功能。您将在变量$uid1中获取字符串的第一部分,在变量$uid2中获取第二部分。您可能不需要变量中的变量(如果您不需要使用超过select的变量,则可以从相应select的{​​{1}}中的变量中替换xsl:value-of一次或用于其他处理指令)。

答案 2 :(得分:1)

由于您使用的是XSLT 2.0处理器,我建议您查看正则表达式,我认为这是2.0以上的优势之一

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:output indent="yes" method="xml"/>
  <xsl:template match="PredecessorActivityUID">
    <root>
      <PredecessorActivityUID1><xsl:value-of select="replace(.,'(^[^-]*)-(.*)','$1')"/></PredecessorActivityUID1>
      <PredecessorActivityUID2><xsl:value-of select="replace(.,'(^[^-]*)-(.*)','$2')"/></PredecessorActivityUID2>
    </root>
  </xsl:template>

</xsl:stylesheet>

这里不需要它们,但了解它们很有用。

答案 3 :(得分:1)

我建议tokenize() ...

XML输入

<doc>
    <PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>    
</doc>

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="PredecessorActivityUID">
        <xsl:for-each select="tokenize(normalize-space(),'-')">
            <xsl:element name="PredecessorActivityUID{position()}">
                <xsl:value-of select="."/>
            </xsl:element>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

<强>输出

<doc>
   <PredecessorActivityUID1>000005001302</PredecessorActivityUID1>
   <PredecessorActivityUID2>0030</PredecessorActivityUID2>
</doc>