英文:
Concatenate variable and lookup expression
问题
使用json-doc(),我将JSON存储在变量$db.data.work中。
然后我处理XML,其中有如下占位符:
<persName>{API:?*[?role_en='Composer']?person?firstName} {API:?*[?role_en='Composer']?person?lastName})</persName>
思路是使用"API:"后面的部分来从$db.data.work中检索值并替换占位符。如何将变量和查找表达式连接起来以便进行评估?
<template name="replace.api.placeholders">
    <variable name="pattern.api.placeholders" as="xs:string" expand-text="no">\{API:(.+?)\}</variable>
    <analyze-string select="." regex="{$pattern.api.placeholders}">
      <matching-substring>
        <value-of select="
            let $db.key := regex-group(1)
            return
              if ($db.data.work?{$db.key}) then
                $db.data.work?{$db.key}
              else
                ."/>
      </matching-substring>
      <non-matching-substring>
        <value-of select="."/>
      </non-matching-substring>
    </analyze-string>
  </template>
我尝试将两者连接为字符串,然后使用大括号或不使用大括号进行评估。
<value-of select="
                let $statement :=     '$db.data.work' || '?persons?*[?role_en=\"Composer\"]?person?firstName' 
                return
                  if ({$statement}) then
                            {$statement}
                  else              
                      ."/>
请注意,只注入一个键正常工作:
<value-of select="
                let $db.key := regex-group(1)
                return
                  if ($db.data.work?($db.key)) then
                    $db.data.work?($db.key)
                  else              
                      ."/>
英文:
Using json-doc() I store JSON in a variable $db.data.work.
Then I process XML where I have placeholders like this
<persName>{API:?*[?role_en='Composer']?person?firstName} {API:?*[?role_en='Composer']?person?lastName})</persName>
The idea is to use the part after "API:" in order to retrieve the values from $db.data.work and replace the placeholders. How could I concatenate the variable and the lookup expressions in order them to be evaluated?
<template name="replace.api.placeholders">
    <variable name="pattern.api.placeholders" as="xs:string" expand-text="no">\{API:(.+?)\}</variable>
    <analyze-string select="." regex="{$pattern.api.placeholders}">
      <matching-substring>
        <value-of select="
            let $db.key := regex-group(1)
            return
              if ($db.data.work<appended-retrieved-expression>) then
                $db.data.work<appended-retrieved-expression
                else
                  ."/>
      </matching-substring>
      <non-matching-substring>
        <value-of select="."/>
      </non-matching-substring>
    </analyze-string>
  </template>
I naively tried to concatenate both as strings and then evaluate using the curly braces or without.
    <value-of select="
                let $statement :=     '$db.data.work' || '?persons?*[?role_en=\"Composer\"]?person?firstName' 
                return
                  if ({$statement}) then
                            {$statement}
                  else              
                      ."/>
Note that just injecting one key works fine:
    <value-of select="
                let $db.key := regex-group(1)
                return
                  if ($db.data.work?($db.key)) then
                    $db.data.work?($db.key)
                  else              
                      ."/>
答案1
得分: 1
使用 xsl:evaluate:
<xsl:evaluate xpath="regex-group(1)" context-item="$db.data.work"/>
需要 Saxon 10 或更高版本用于 HE,对于 PE 和 EE 9.8 或更高版本。
最小示例(您的输入):
<persName>{API:?*[?role_en='Composer']?person?firstName} {API:?*[?role_en='Composer']?person?lastName})</persName>
XSLT:
<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-copy"/>
  <xsl:template match="persName">
    <xsl:variable name="pattern.api.placeholders" as="xs:string" expand-text="no">{API:(.+?)}</xsl:variable>
    <xsl:analyze-string select="." regex="{$pattern.api.placeholders}">
      <xsl:matching-substring>
        <xsl:evaluate xpath="regex-group(1)" context-item="$db.data.work"/>
      </xsl:matching-substring> 
    </xsl:analyze-string>
  </xsl:template>
  
  <xsl:param name="db.data.work" select="parse-json($json-string)"/>
  
  <xsl:param name="json-string" as="xs:string" expand-text="no">[
    { "role_en" : "Composer", "person": { "firstName": "Johann Sebastian", "lastName":"Bach" } }
  ]</xsl:param>
  
</xsl:stylesheet>
英文:
Use xsl:evaluate:
<xsl:evaluate xpath="regex-group(1)" context-item="$db.data.work"/>
Needs Saxon 10 or higher for HE, for PE and EE 9.8 or higher.
Minimal example (your input):
<persName>{API:?*[?role_en='Composer']?person?firstName} {API:?*[?role_en='Composer']?person?lastName})</persName>
XSLT
<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-copy"/>
  <xsl:template match="persName">
    <xsl:variable name="pattern.api.placeholders" as="xs:string" expand-text="no">\{API:(.+?)\}</xsl:variable>
    <xsl:analyze-string select="." regex="{$pattern.api.placeholders}">
      <xsl:matching-substring>
        <xsl:evaluate xpath="regex-group(1)" context-item="$db.data.work"/>
      </xsl:matching-substring> 
    </xsl:analyze-string>
  </xsl:template>
  
  <xsl:param name="db.data.work" select="parse-json($json-string)"/>
  
  <xsl:param name="json-string" as="xs:string" expand-text="no">[
    { "role_en" : "Composer", "person": { "firstName": "Johann Sebastian", "lastName":"Bach" } }
  ]</xsl:param>
  
</xsl:stylesheet>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论