如何从动态行获取数据

时间:2011-07-25 12:45:43

标签: xml xslt xpath

是否可以在第二个符号;之后获取数据? 例如,我有这个XML:

<document>
    <line>H;1F;ss;232</line>
    <line>H2;1F;sss;232e</line>
    <line>H;15F5;sds;232sa;23</line>
    <line>Hh;1Fs;scs;232ds</line>
</document>

结果应为:

<document>
    <line>ss</line>
    <line>sss</line>
    <line>sds</line>
    <line>scs</line>
</document>

2 个答案:

答案 0 :(得分:2)

使用substring-beforesubstring-after功能,即:

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

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

    <xsl:template match="line">
        <xsl:copy>
            <xsl:value-of select="substring-before(substring-after(substring-after(., ';'), ';'), ';')"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

结果:

<document>
    <line>ss</line>
    <line>sss</line>
    <line>sds</line>
    <line>scs</line>
</document>

答案 1 :(得分:2)

<强>予。使用FXSL的XSLT 1.0解决方案:

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
  exclude-result-prefixes="ext">
   <xsl:import href="strSplit-to-Words.xsl"/>
   <xsl:output indent="yes" omit-xml-declaration="yes"/>
   <xsl:strip-space elements="*"/>

    <xsl:template match="/*">
     <document>
      <xsl:apply-templates/>
     </document>
    </xsl:template>

    <xsl:template match="line">
      <xsl:variable name="vwordNodes">
        <xsl:call-template name="str-split-to-words">
          <xsl:with-param name="pStr" select="."/>
          <xsl:with-param name="pDelimiters" 
                          select="';'"/>
        </xsl:call-template>
      </xsl:variable>

      <line>
       <xsl:value-of select="ext:node-set($vwordNodes)/*[3]"/>
      </line>
    </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<document>
    <line>H;1F;ss;232</line>
    <line>H2;1F;sss;232e</line>
    <line>H;15F5;sds;232sa;23</line>
    <line>Hh;1Fs;scs;232ds</line>
</document>

生成想要的正确结果

<document>
   <line>ss</line>
   <line>sss</line>
   <line>sds</line>
   <line>scs</line>
</document>

<强>解释

  1. 我们使用FXSL中的str-split-to-words模板来拆分每个line元素的字符串值。请注意,它不允许只有一个字符,但要在其pDelimiters参数中指定多个字符。在这种情况下,我们仅指定';'

  2. 结果作为RTF在变量中捕获。我们使用ext:node-set()扩展函数将其转换为普通树。如果您的XSLT处理器没有实现ext:node-set(),请查看其特定XSLT处理器实现的xxx:node-set()扩展名的名称和命名空间。

  3. 从这样获得的树中,我们只选择并输出第3个元素。请注意,这是一个简短的XPath表达式,即使我们想要第20个元素,也会使用相同的短XPath表达式 - 只需要索引为20.只使用一系列{这是不可能以简洁的形式实现的。 {1}}函数。

  4. <强> II。这是一个简短易用的XSLT 2.0解决方案:

    substring-after()

    在提供的XML文档上使用此转换时

    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="/*">
         <document>
          <xsl:apply-templates/>
         </document>
     </xsl:template>
    
     <xsl:template match="line">
      <document>
       <xsl:value-of select="tokenize(., ';')[3]"/>
      </document>
     </xsl:template>
    </xsl:stylesheet>
    

    产生了想要的正确结果

    <document>
        <line>H;1F;ss;232</line>
        <line>H2;1F;sss;232e</line>
        <line>H;15F5;sds;232sa;23</line>
        <line>Hh;1Fs;scs;232ds</line>
    </document>