Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String XSLT:用字符串替换整数_String_Xslt_Int_Match - Fatal编程技术网

String XSLT:用字符串替换整数

String XSLT:用字符串替换整数,string,xslt,int,match,String,Xslt,Int,Match,我有个小问题。 XML中的节点可能包含和整数,我必须用字符串替换这个整数。 每个数字与一个字符串匹配 例如,我有: <root> <status>1</status> </root> <root> <status>TODO</status> </root> 整数字符串 1-待办事项 2-进行中 3-完成 4-错误 5-中止 原始XML

我有个小问题。 XML中的节点可能包含和整数,我必须用字符串替换这个整数。 每个数字与一个字符串匹配

例如,我有:

    <root>
       <status>1</status>
    </root>
    <root>
       <status>TODO</status>
    </root>

整数字符串

1-待办事项

2-进行中

3-完成

4-错误

5-中止


原始XML:

    <root>
       <status>1</status>
    </root>
    <root>
       <status>TODO</status>
    </root>

1.

转换的XML:

    <root>
       <status>1</status>
    </root>
    <root>
       <status>TODO</status>
    </root>

待办事项
所以我想用“TODO”替换1,用“进行中”替换2



我在问是否还有其他方法可以做到这一点。

最简单的方法是从身份转换开始,然后添加特殊情况:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="status[. = '1']">
    <status>TODO</status>
  </xsl:template>
  <!-- likewise for status[. = '2'] etc. -->

  <!-- copy everything else -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

待办事项

最简单的方法是从身份转换开始,然后添加特殊情况:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="status[. = '1']">
    <status>TODO</status>
  </xsl:template>
  <!-- likewise for status[. = '2'] etc. -->

  <!-- copy everything else -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

待办事项

一种方法是创建一种“查找”值表。这可以嵌入到XSLT中,或者放在单独的文件中。例如,如果将其放在XSLT文件中,它将如下所示

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
   xmlns:lookup="lookup">

<lookup:data>
   <status code="1">TO DO</status>
   <status code="2">IN PROGRESS</status>
   <status code="3">DONE</status>
</lookup:data>

做
进行中
完成
然后,您还将创建一个变量来访问此数据

<xsl:variable name="lookup" select="document('')/*/lookup:data"/>

最后,要查找值,只需执行以下操作

<xsl:value-of select="$lookup/status[@code = '1']/>

一种方法是创建一种“查找”值表。这可以嵌入到XSLT中,或者放在单独的文件中。例如,如果将其放在XSLT文件中,它将如下所示

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
   xmlns:lookup="lookup">

<lookup:data>
   <status code="1">TO DO</status>
   <status code="2">IN PROGRESS</status>
   <status code="3">DONE</status>
</lookup:data>

做
进行中
完成
然后,您还将创建一个变量来访问此数据

<xsl:variable name="lookup" select="document('')/*/lookup:data"/>

最后,要查找值,只需执行以下操作

<xsl:value-of select="$lookup/status[@code = '1']/>

您的解决方案中有许多不必要的代码。以下是一个简化版本,其工作方式相同:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
        <xsl:template match="/root/status"> 
<root> 
  <status> 
            <xsl:choose> 
                <xsl:when test="contains(.,'1')">TODO</xsl:when> 
                <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise> 
            </xsl:choose> 
  </status>
 </root> 
        </xsl:template> 
</xsl:stylesheet> 

待办事项

您的解决方案中有许多不必要的代码。以下是一个简化版本,其工作方式相同:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
        <xsl:template match="/root/status"> 
<root> 
  <status> 
            <xsl:choose> 
                <xsl:when test="contains(.,'1')">TODO</xsl:when> 
                <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise> 
            </xsl:choose> 
  </status>
 </root> 
        </xsl:template> 
</xsl:stylesheet> 

待办事项

我的话。XSLT并不容易,我不认为应该通过展示您对内部工作原理的了解(如其他一些答案所示)来让它变得比需要的更难

为了让你一针见血,可以使用Choose语句。我可能会把它拉到一个单独的模板中(我在其他语言中使用类似的方法),只是为了简化测试并帮助清理代码以便于阅读

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="PrintStatus">
  <!-- param we can pass a value into or default to the current node -->
  <xsl:param name="text" select="." />  
  <xsl:choose>
    <xsl:when test="contains($text, '1')">
      <xsl:value-of select="'TODO'"/>
    </xsl:when>
    <!-- Assume your others go here -->
    <xsl:otherwise>
      <xsl:value-of select="$text"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="/root/status">
  <root>
    <status>
      <xsl:call-template name="PrintStatus" />
    </status>
  </root>
</xsl:template>

</xsl:stylesheet>


保持简单,除非你需要额外的麻烦。

我的话。XSLT并不容易,我不认为应该通过展示您对内部工作原理的了解(如其他一些答案所示)来让它变得比需要的更难

为了让你一针见血,可以使用Choose语句。我可能会把它拉到一个单独的模板中(我在其他语言中使用类似的方法),只是为了简化测试并帮助清理代码以便于阅读

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="PrintStatus">
  <!-- param we can pass a value into or default to the current node -->
  <xsl:param name="text" select="." />  
  <xsl:choose>
    <xsl:when test="contains($text, '1')">
      <xsl:value-of select="'TODO'"/>
    </xsl:when>
    <!-- Assume your others go here -->
    <xsl:otherwise>
      <xsl:value-of select="$text"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="/root/status">
  <root>
    <status>
      <xsl:call-template name="PrintStatus" />
    </status>
  </root>
</xsl:template>

</xsl:stylesheet>


除非您需要额外的复杂性,否则请保持简单。

在这种情况下,我有时会使用一个技巧,即在一个字符串中使用值列表,并获取一个子字符串,如下所示:

<xsl:variable name="statuslist">TODO       IN PROGRESSDONE       ERROR      ABORTED    </xsl:variable>

<xsl:template match="status/text()">
  <xsl:value-of select="normalize-space(substring($statuslist, ( . - 1 ) * 11 , 11))" />
</xsl:template>
PROGRESSDONE中的TODO错误中止
注意,“statuslist”中的值正好相隔11个字符(最长值的长度),因此子字符串中的*11和,11。因为从1开始计算而不是从0开始,所以必须从索引中减去1。或者,您可以在变量的开头填充11个空格,而不是减去1,这取决于您自己。
normalize space
调用只是从提取的值中去掉多余的空格

如果您想使它更整洁,可以在每个值之间放置一个分隔符,并在
子字符串调用中使用
*12,11


如果您有大量可能的值,那么这个解决方案就不能很好地扩展,而且很明显,它需要您的可能ID处于一个序列中,但是如果只有几个值,它就相当紧凑。

在这种情况下,我有时会使用一个技巧,即在一个字符串中使用一个值列表,并获取一个子字符串,如下所示:

<xsl:variable name="statuslist">TODO       IN PROGRESSDONE       ERROR      ABORTED    </xsl:variable>

<xsl:template match="status/text()">
  <xsl:value-of select="normalize-space(substring($statuslist, ( . - 1 ) * 11 , 11))" />
</xsl:template>
PROGRESSDONE中的TODO错误中止
注意,“statuslist”中的值正好相隔11个字符(最长值的长度),因此子字符串中的*11和,11。因为从1开始计算而不是从0开始,所以必须从索引中减去1。或者,您可以在变量的开头填充11个空格,而不是减去1,这取决于您自己。
normalize space
调用只是从提取的值中去掉多余的空格

如果您想使它更整洁,可以在每个值之间放置一个分隔符,并在
子字符串调用中使用
*12,11


如果您有大量可能的值,那么它不是一个可以很好地扩展的解决方案,而且显然它需要您的可能ID处于一个序列中,但是如果只有几个值,那么它是相当紧凑的。

有很多方法可以做到这一点。如果转换是从1到N范围内的连续整数,我将使用

<xsl:variable name="index" select="xs:integer(status)"/>
<xsl:value-of select="('TODO', 'IN PROGRESS', 'DONE', 'ERROR', 'ABORTED')[$index]"/>

在有少量值的其他情况下,我可能会使用模板规则:

<xsl:template match="status[.='1']" mode="lookup">TODO</xsl:template>
<xsl:template match="status[.='2']" mode="lookup">IN PROGRESS</xsl:template>
待办事项 进行中
等等

在其他情况下,查找表会产生