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

xslt replace()函数似乎不工作

  •  0
  • Ironluca  · 技术社区  · 6 年前

    我正在使用XSLT将XML模式转换为JSON格式,其中有一个模式方面,如下所示:

                    <simpleType>
                    <restriction base="string">
                        <pattern value="[A-Z0-9a-z_]+(@\{UUID\}|@\{TIMEMILLIS\})?[A-Z0-9a-z]*"/>
                    </restriction>
                </simpleType>
    

    虽然regex转义需要'\'字符,但在转换为json时,它们需要进一步转义。

    我将XSLT3.0与Saxon结合使用,如下所示:

    <if test="child::xsi:simpleType/child::xsi:restriction/child::xsi:pattern">
        <text>,"pattern":"</text><value-of select="replace(attribute::value,'\\','\\')"/><text>"</text>
    </if>
    

    输出结果仍然是

    "pattern": "[A-Z0-9a-z_]+(@\{UUID\}|@\{TIMEMILLIS\})?[A-Z0-9a-z]*"
    

    在JSON中。我尝试过很多组合,replace()函数在这里似乎不起作用。

    我可能错过了什么。我指的是函数定义 here .

    任何帮助都将不胜感激。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Michael Kay    6 年前

    替代 \ 具有 \\ ,你需要写

    replace($x, '\\', '\\\\')
    

    这是因为替换字符串中的转义规则。(规则选择不当,我们试图与其他语言兼容,但其他语言在这方面完全不一致。)

    还有另一种选择:使用“q”标志:

    replace($x, '\', '\\', 'q')
    
        2
  •  1
  •   Martin Honnen    6 年前

    使用xslt和xpath 3中的支持创建和序列化JSON,例如创建映射和序列化为JSON。

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:mode on-no-match="shallow-skip"/>
    
      <xsl:output method="json" indent="yes"/>
    
      <xsl:template match="pattern">
          <xsl:sequence select="map { local-name() : data(@value) }"/>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/pPzifoX

    或者创建XML格式, xml-to-json 函数应为:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns="http://www.w3.org/2005/xpath-functions"
        exclude-result-prefixes="#all"
        expand-text="yes"
        version="3.0">
    
      <xsl:mode on-no-match="shallow-skip"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:output method="text" indent="yes"/>
    
      <xsl:variable name="json-xml">
          <xsl:apply-templates/>
      </xsl:variable>
    
      <xsl:template match="/">
          <xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
      </xsl:template>
    
      <xsl:template match="pattern">
          <map>
              <string key="{local-name()}">{@value}</string>
          </map>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/pPzifoX/1