代码之家  ›  专栏  ›  技术社区  ›  Benoit

用文本和节点数组替换字符串

  •  0
  • Benoit  · 技术社区  · 7 年前

    假设我有以下XML输入:

    <?xml version="1.0"?>
    <root>
      <urls>
        <url>http://foo</url>
        <url>http://bar</url>
      </urls>
      <resources lang="en-US">
        <resourceString id='url-fmt'>See URL: {0}</resourceString>
      </resources>
    </root>
    

    我想用xsl生成以下输出(可以使用1.0、2.0甚至3.0):

    <?xml version="1.0"?>
    <body>
      <p>See URL: <a href="http://foo">http://foo</a></p>
      <p>See URL: <a href="http://bar">http://bar</a></p>
    </body>
    

    我有以下xsl样式表存根,但是我很难找到合适的函数来标记资源字符串,提取{0}并用节点替换它。 replace() 似乎没有帮助,因为它只使用字符串:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
      <xsl:variable name="urlResString"
                    select="/root/resources/resourceString[@id='url-fmt']" />
      <xsl:template match="/">
        <body>
          <xsl:apply-templates select="/root/urls/url" />
        </body>
      </xsl:template>
      <xsl:template match="url">
        <p>
          <xsl:variable name='linkToInsert'>
            <a href='{.}'><xsl:value-of select='.'/></a>
          </xsl:variable>
          <xsl:value-of
               select="replace($urlResString, '\{0}', $linkToInsert)" />
        </p>
      </xsl:template>
    </xsl:stylesheet>
    

    这里产生的是:

    <?xml version="1.0"?>
    <body>
      <p>See URL: http://foo</p>
      <p>See URL: http://bar</p>
    </body>
    

    如果你能指导我使用正确的函数,那就太好了。

    注意:我可能要用两个字符串 {0} , {1} 等等,有点像.net中的格式字符串函数。

    谢谢!

    2 回复  |  直到 7 年前
        1
  •  2
  •   Joel M. Lamsen    7 年前

    你可以使用 xsl:analyze-string 如下:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:variable name="urlResString"
            select="/root/resources/resourceString[@id='url-fmt']" />
        <xsl:template match="/">
            <body>
                <xsl:apply-templates select="/root/urls/url" />
            </body>
        </xsl:template>
        <xsl:template match="url">
            <p>
                <xsl:variable name='linkToInsert'>
                    <a href='{.}'><xsl:value-of select='.'/></a>
                </xsl:variable>
                <xsl:analyze-string select="$urlResString" regex="\{{\d\}}">
                    <xsl:matching-substring>
                        <xsl:copy-of select="$linkToInsert"/>
                    </xsl:matching-substring>
                    <xsl:non-matching-substring>
                        <xsl:copy/>
                    </xsl:non-matching-substring>
                </xsl:analyze-string>
            </p>
        </xsl:template>
    </xsl:stylesheet>
    
        2
  •  1
  •   imran    7 年前
     <xsl:template match="root/urls">
            <body>
            <xsl:for-each select="url">
                <p>
                    <xsl:value-of select=" substring-before(parent::urls/following-sibling::resources/resourceString,' {')"/><xsl:text> </xsl:text>
                    <a href="{.}"><xsl:value-of select="."/></a>
                </p>
            </xsl:for-each>
            </body>
        </xsl:template>
        <xsl:template match="resources"/>
    Try it