简体   繁体   English

未捕获的类型错误:无法读取 null 的属性(读取“hashCode”)[SaxonJS]

[英]Uncaught TypeError: Cannot read properties of null (reading 'hashCode') [SaxonJS]

I'm getting this error in Chrome console:我在 Chrome 控制台中收到此错误:

在此处输入图像描述

Seems to be a problem with XSLT or SEF as other SEF works.似乎是 XSLT 或其他 SEF 工作的 SEF 的问题。 I complie SEF with the xslt3 tool on Node.js version v14.17.3.我在 Node.js 版本 v14.17.3 上使用xslt3工具编译 SEF。

I can run the XSLT with Saxon 9.8.12-EE in oXygen with no problem.我可以在 oXygen 中使用 Saxon 9.8.12-EE 运行 XSLT 没有问题。

Maybe the problem with maps, xsl:include or xsl:import ?也许是地图、 xsl:includexsl:import的问题?

Here is the XSLT code:这是 XSLT 代码:


<stylesheet exclude-result-prefixes="xs xd dme functx dita mei map array" extension-element-prefixes="ixsl" version="3.0" xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:dita="http://dita-ot.sourceforge.net" xmlns:dme="http://www.mozarteum.at/ns/dme" xmlns:functx="http://www.functx.com" xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:mei="http://www.music-encoding.org/ns/mei" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.music-encoding.org/ns/mei">


  <xi:include href="docs.xsl" xpointer="element(/1/1)"/>
  <import href="changeLog.xsl"/>



  <!--This parameter is a needed for XSpec. Cf. https://github.com/xspec/xspec/wiki/Global-Context-Item-->
  <param name="global-context-item" select="."/>

  <param name="source"/>


  <include href="../modules/identity-transform.xsl"/>


  <xd:doc>
    <xd:desc>
      <xd:p>Replace current scoreDef with the alternative. Note that this should be defined in the following-sibling &lt;choice&gt;.</xd:p>
    </xd:desc>
  </xd:doc>
  <template match="scoreDef[not(@corresp = concat('#', $source))]">
    <copy-of select="following-sibling::choice[@type = 'scoring']/*[@corresp = concat('#', $source)]/scoreDef"/>

  </template>

  <xd:doc>
    <xd:desc/>
  </xd:doc>
  <template match="choice[@type = 'scoring']"/>

  <xd:doc>
    <xd:desc>
      <xd:p>Map staffDef@n of the new scoreDef and @dme.parts.</xd:p>
    </xd:desc>
  </xd:doc>
  <variable as="map(xs:string, item())*" name="map_staves_order">
    <for-each select="$global-context-item//choice[@type = 'scoring']/*[@corresp = concat('#', $source)]/scoreDef">
      <map>
        <for-each select="descendant::staffDef">
          <map-entry key="string(@n)" select="@dme.parts"/>
        </for-each>
      </map>
    </for-each>
  </variable>

  <xd:doc>
    <xd:desc>
      <xd:p>Get the maximum number of staves.</xd:p>
    </xd:desc>
  </xd:doc>
  <variable as="xs:integer" name="count_staves" select="
      max(for $a in map:keys($map_staves_order)
      return
        if (matches($a, '\d')) then
          xs:integer($a)
        else
          ())"/>


  <xd:doc>
    <xd:desc>
      <xd:p>Key: old @n.</xd:p>
      <xd:p>Value: new @n</xd:p>
    </xd:desc>
  </xd:doc>
  <variable as="map(xs:string, xs:string)*" name="map_new_old_staves">
    <map>
      <for-each select="map:keys($map_staves_order)">
        <variable name="current_key" select="."/>
        <map-entry key="$global-context-item//measure[@n = 1]/staff[@dme.parts = map:get($map_staves_order, $current_key)]/@n/string()" select="."/>
      </for-each>
    </map>

  </variable>



  <xd:doc>
    <xd:desc>
      <xd:p>Copies elements before first staff without changes, e.g. &lt;tempo&gt;</xd:p>
      <xd:p>Copies staves accordingly to the new score order. Changes the @n-attribute accordingly</xd:p>
      <xd:p>Copies ControlEvents and updates the @staff attribute if neccessary.</xd:p>
    </xd:desc>
  </xd:doc>
  <template match="measure">
    <copy>
      <apply-templates select="@*"/>
      <apply-templates select="child::staff[1]/preceding-sibling::*"/>

      <variable as="element()" name="currentMeasure" select="."/>
      <for-each select="1 to $count_staves">
        <variable as="xs:string" name="currentItem" select="string()"/>
        <for-each select="$currentMeasure/child::staff[map:get($map_staves_order, $currentItem) = @dme.parts]">
          <copy>
            <attribute name="n" select="$currentItem"/>
            <apply-templates select="(@* except @n) | node()"/>
          </copy>
        </for-each>
      </for-each>

      <call-template name="update_staff_controlEvents">
        <with-param name="elements" select="child::staff[last()]/following-sibling::*"/>
      </call-template>
    </copy>
  </template>



  <xd:doc>
    <xd:desc>
      <xd:p>Receives one or more elements (controlEvents) and updates their @staff according to the $map_new_old_staves variable.</xd:p>
      <xd:p>Recursive template</xd:p>
    </xd:desc>
    <xd:param name="elements"/>
  </xd:doc>
  <template name="update_staff_controlEvents">
    <param name="elements"/>

    <for-each select="$elements">
      <choose>
        <when test="@staff">
          <copy>
            <attribute name="staff" select="map:get($map_new_old_staves, @staff)"/>
            <apply-templates select="@* except @staff"/>
            <if test="node()">
              <call-template name="update_staff_controlEvents">
                <with-param name="elements" select="node()"/>
              </call-template>
            </if>
          </copy>
        </when>
        <otherwise>
          <copy>
            <apply-templates select="@*"/>
            <if test="node()">
              <call-template name="update_staff_controlEvents">
                <with-param name="elements" select="node()"/>
              </call-template>
            </if>
          </copy>
        </otherwise>
      </choose>
    </for-each>
  </template>

</stylesheet>

JS which I run on Console:我在控制台上运行的 JS:



var options = {
      stylesheetLocation: "./assets/xsl/origScoring.sef.json",
         sourceText: xmlString,    
           stylesheetParams: {"source": "source_A"},
         destination: "document"
}

var result = SaxonJS.transform(options);
result.principalResult

Owing to the Saxon developers I could easily solve my issue by adding namespace prefixes in the XPath expressions when creating maps.由于Saxon 开发人员,我可以通过在创建地图时在 XPath 表达式中添加名称空间前缀轻松解决我的问题。 Originally, I used xpath-default-namespace .最初,我使用xpath-default-namespace Fo instance, here on the elements measure and staff should be:例如,这里的要素measurestaff应该是:

<map-entry key="$global-context-item//mei:measure[@n = 1]/mei:staff[@dme.parts = map:get($map_staves_order, $current_key)]/@n/string()" select="."/>

instead of代替

<map-entry key="$global-context-item//measure[@n = 1]/staff[@dme.parts = map:get($map_staves_order, $current_key)]/@n/string()" select="."/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM