xslt 节点替换然后用 javascript 摄取

Posted

技术标签:

【中文标题】xslt 节点替换然后用 javascript 摄取【英文标题】:xslt node replace then ingest with javascript 【发布时间】:2021-11-29 06:50:51 【问题描述】:

在摄取到 NoSQL (marklogic) 数据库之前,我根据特定路径替换内存中的 XML 节点。

输入:/doc1.xml

<image xmlns="http://coin/decimal">
      <DE>
         <denomination>1pf</denomination>
            <reverse>rye stalks</reverse>
            <obverse>oak sprig</obverse>
            <before>Anglo–Saxons</before>
      </DE>
      <GBP>
          <denomination>1p</denomination>
            <reverse>Arms</reverse>
            <obverse>Queen</obverse>
            <before>Anglo–Saxons</before>
      </GBP>
</image>

我将/before:image/before:DE/before:before 值替换为参数值 Xsl:

const beforeXsl =
 fn.head(xdmp.unquote(
`  <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:before="http://coin/decimal"  version="2.0">
 
    <xsl:template match="/Qhttp://coin/decimalimage/Qhttp://coin/decimalDE/Qhttp://coin/decimalbefore">
            <xsl:element name="local-name()">
                <xsl:value-of select="$replace"/>
            </xsl:element>
    </xsl:template>
 
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
 
  </xsl:transform>
`));
 
xdmp.xsltEval(beforeXsl, doc, params)

预期输出:

<image xmlns="http://coin/decimal">
      <DE>
         <denomination>1pf</denomination>
            <reverse>rye stalks</reverse>
            <obverse>oak sprig</obverse>
            <before>Anglo-Dutch</before>
      </DE>
      <GBP>
          <denomination>1p</denomination>
            <reverse>Arms</reverse>
            <obverse>Queen</obverse>
            <before>Anglo–Saxons</before>
      </GBP>
</image>

我尝试参数化我的 xsl,但收到错误:

[javascript] XSLT-BADPATTERN: MarkLogic extension syntax used, EQNames are not supported in XSLT mode

【问题讨论】:

看看这是否有帮助:***.com/a/34762628/3016153 @Mads Hansen 和 @michael.hor257k,感谢您的帮助。 - Qname 在其他 XSL 编辑器中有效,但在 Marklogic 中无效。 - 我使用静态 EQname,因为我不知道其他方式将路径作为参数传递。 Fiona 提供 xdmp:path 是正确的。现在我可以将路径作为参数传递。 - 她修复了我错过的东西:namespace。如果示例文档有不同的名称空间或没有名称空间,那么它会被错误地转换。我希望我能把我的观点说清楚。我们很高兴看到 xslt 发生。 【参考方案1】:

为什么!不应该是吗

var params = ;
params.nsProduct = "http://coin/decimal"
params.qPath = "/before:image/before:DE/before:before"
params.replaceValue="Anglo-Dutch"

const implReplace = fn.head(xdmp.unquote(
`
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:before="http://coin/decimal"  
    exclude-result-prefixes="#all" version="2.0">
    
    <xsl:param name="nsProduct"/>
    <xsl:param name="qPath"/>
    <xsl:param name="replaceValue" as="xs:anyAtomicType"/>
    
    <xsl:template match="node()[(xdmp:path(.) eq $qPath)]">
        <xsl:variable name="replace">
            <xsl:element name="local-name()" namespace="$nsProduct">
                <xsl:value-of select="$replaceValue"/>
            </xsl:element>
        </xsl:variable>
        <xsl:sequence select="$replace"/>
    </xsl:template>
    
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:transform>

`));

xdmp.xsltEval(implReplace, doc, params)

【讨论】:

女士。菲奥娜:答案恰到好处!非常感谢!【参考方案2】:

EQname 在 XSLT 2.0 样式表中不受支持。您正尝试在 @match 表达式中使用它们。

改为使用您已经在 XSLT 的 @match 表达式的 XPath 中定义的 before 命名空间前缀:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:before="http://coin/decimal"  version="2.0">

  <xsl:param name="replace"/>

  <xsl:template match="/before:image/before:DE/before:before">
        <xsl:element name="local-name()">
            <xsl:value-of select="$replace"/>
        </xsl:element>
  </xsl:template>

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

</xsl:transform>

您还需要为当前未定义的$replace 定义xsl:paramxsl:variable

【讨论】:

以上是关于xslt 节点替换然后用 javascript 摄取的主要内容,如果未能解决你的问题,请参考以下文章

XSLT如何仅对XML文档的字符串节点中的数值进行排序

如何使用 XSLT 替换 XML 节点名称中的字符 - 更改根元素

用 XSLT 替换 XML 属性中的换行符

用XSLT替换f:facet属性

用XSLT替换xml中的break元素

在 msxsl 中将节点作为参数传递:来自 XSLT for-each 的脚本 javascript 函数不起作用