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

Xml 元素需要在xsl中拆分为两个元素,xml,xslt,xslt-2.0,Xml,Xslt,Xslt 2.0,我有元素 <PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>` 000005001302-0030` 在XSLT2.0中,我需要将其拆分为两个元素,如下所示: <PredecessorActivityUID1>000005001302</PredecessorActivityUID1> <PredecessorActivityUID2>0030<

我有元素

<PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>`
000005001302-0030`
在XSLT2.0中,我需要将其拆分为两个元素,如下所示:

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

将两个不同的变量PredecessorActivityUID1,PredecessorActivityUID2

我刚刚尝试使用子字符串函数。看看是否有用

<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>

我刚刚尝试了子字符串功能。看看是否有用

<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>

在本文档中:

<PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>
000005001302-0030
使用此样式表:

<?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>

000005001302
0030

这里不一定需要递归模板,特别是对于这样一个简单的需求。如果你必须把绳子分成多个部分,那就太好了
tokenize()
非常好,您的处理器将支持它,但您的需求非常简单,因此代码可能更清晰(在这里使用正则表达式可能会有过多的可维护性)

这将适用于XSLT1.0或2.0,并且不需要任何扩展或特定于处理器的特殊函数。您将在变量
$uid1
中获得字符串的第一部分,在变量
$uid2
中获得字符串的第二部分。变量中可能不需要这些值(如果不需要多次使用这些值或用于其他处理指令,则可以从相应的
xsl:value of
select
中的变量中替换
select

<PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>
000005001302-0030
使用此样式表:

<?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>

000005001302
0030

这里不一定需要递归模板,特别是对于这样一个简单的需求。如果你必须把绳子分成多个部分,那就太好了
tokenize()
非常好,您的处理器将支持它,但您的需求非常简单,因此代码可能更清晰(在这里使用正则表达式可能会有过多的可维护性)


这将适用于XSLT1.0或2.0,并且不需要任何扩展或特定于处理器的特殊函数。您将在变量
$uid1
中获得字符串的第一部分,在变量
$uid2
中获得字符串的第二部分。变量中可能不需要这些值(如果不需要多次使用这些值或用于其他处理指令,则可以从相应的
xsl:value of
select
中的变量中替换
select

因为您使用的是XSLT 2.0处理器,我建议大家看看正则表达式,我认为它是2.0比1.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>


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

因为您使用的是XSLT 2.0处理器,我建议您看看正则表达式,我认为正则表达式是2.0优于1.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>

这里不需要它们,但认识它们很好。

我推荐

XML输入

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

000005001302-0030    
XSLT2.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>
    <PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>    
</doc>
<doc>
   <PredecessorActivityUID1>000005001302</PredecessorActivityUID1>
   <PredecessorActivityUID2>0030</PredecessorActivityUID2>
</doc>

000005001302
0030
我建议

XML输入

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

000005001302-0030    
XSLT2.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>
    <PredecessorActivityUID>000005001302-0030</PredecessorActivityUID>    
</doc>
<doc>
   <PredecessorActivityUID1>000005001302</PredecessorActivityUID1>
   <PredecessorActivityUID2>0030</PredecessorActivityUID2>
</doc>

000005001302
0030

您可能想使用函数。花几分钟时间格式化您的问题。你把文本和代码混合在一个代码标记中,下面很难阅读。(也许你可以说一两句你已经尝试过的话)任何字符串函数都可以轻松做到这一点job@Manisha我刚才在评论中为你提到了一个。您可以浏览该链接。您可能希望使用函数。花几分钟时间格式化您的问题。你把文本和代码混合在一个代码标记中,下面很难阅读。(也许你可以说一两句你已经尝试过的话)任何字符串函数都可以轻松做到这一点job@Manisha我刚才在评论中为你提到了一个。你可以浏览链接。这是一个不错的解决方案,但它可能做了比需要更多的工作。他只需要将字符串一分为二,但如果他有一个字符串有多个
-
,即
123-456-789
,这就很好了。这个问题被标记为XSLT 2.0:即使任务是将给定字符串拆分为多个标记,也不需要递归模板。这是一个不错的解决方案,但它可能做的工作比它需要做的更多。他只需要将字符串一分为二,但如果他有一个包含多个
-
的字符串,即
123-456-789
,这将很好。这个问题被标记为XSLT 2.0:不需要递归模板,即使任务是将给定字符串拆分为多个标记。“可能在处理器中不受支持(?)-任何符合标准的XSLT 2.0处理器都将支持
tokenize
。声称支持XSLT2.0但不允许标记化的处理器是在撒谎。啊,好吧。我来编辑。我只是习惯于使用MSXML,它只支持1.0。我相信有一些扩展可以为它提供标记化功能。无论如何,对于这一要求来说,正则表达式可能是矫枉过正的。“可能在您的处理器中不受支持(?)——任何符合XSLT2.0标准的处理器wi