【问题标题】:BaseX XSLT fails after returning first result返回第一个结果后 BaseX XSLT 失败
【发布时间】:2020-05-21 12:53:38
【问题描述】:

我有一个存储在 BaseX 中的大型 XML 文件,我需要将其拆分为更小的模块化文档。为此,我创建了一个 XSL 文件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output indent="yes" encoding="UTF-8"/>
    <xsl:param name="schema"/>
    <xsl:param name="model"/>
    <xsl:param name="sysDiff"/>
    <xsl:param name="sys"/>
    <xsl:param name="subsys"/>
    <xsl:param name="subsubsys"/>
    <xsl:param name="assy"/>
    <xsl:param name="disassy"/>
    <xsl:param name="disassyv"/>
    <xsl:param name="info"/>
    <xsl:param name="infov"/>
    <xsl:param name="itemloc"/>
    <xsl:param name="tname"/>
    <xsl:param name="iname"/>
    <xsl:param name="outputDir"/>

    <xsl:template match="/">
        <xsl:result-document href="{concat($outputDir, '/DMC-',$model,'-',$sysDiff,'-',$sys,'-',$subsys,$subsubsys,'-',$assy,'-',$disassy,$disassyv,'-',$info,$infov,'-',$itemloc,'.xml')}" method="xml">
            <dmodule>
                <identAndStatusSection>
                    <dmAddress>
                        <dmIdent>
                            <dmCode modelIdentCode="{$model}" systemDiffCode="{$sysDiff}">
                                <xsl:attribute name="systemCode" select="$sys"/>
                                <xsl:attribute name="subSystemCode" select="$subsys"/>
                                <xsl:attribute name="subSubSystemCode" select="$subsubsys"/>
                                <xsl:attribute name="assyCode" select="$assy"/>
                                <xsl:attribute name="disassyCode" select="$disassy"/>
                                <xsl:attribute name="disassyCodeVariant" select="$disassyv"/>
                                <xsl:attribute name="infoCode" select="$info"/>
                                <xsl:attribute name="infoCodeVariant" select="$infov"/>
                                <xsl:attribute name="itemLocationCode" select="$itemloc"/>
                            </dmCode>
                            <language languageIsoCode="en" countryIsoCode="US"/>
                            <issueInfo issueNumber="000" inWork="01"/>
                        </dmIdent>
                    </dmAddress>
                </identAndStatusSection>
            </dmodule>
        </xsl:result-document>    
    </xsl:template>
</xsl:stylesheet>

我的问题是在 BaseX 中使用 xslt:transform() 函数时,它只返回(创建)第一个文档。这是我为此准备的 XQuery:

 let $style := doc('file:///C:/base.xsl')

   for $d in doc('file:///C:/Users/tfurst/Documents/Book1-test.xml')//title
      for $newD in //*[title]
      where $newD/title/@id eq $d/@id
        let $schema := $d/schemaName
        let $model := $d/modelic
        let $sdc := $d/sdc
        let $sys := $d/systemCode
        let $subsys := $d/subsys
        let $subsubsys := $d/subsubsys
        let $assy := $d/assy
        let $disassy := $d/disassy
        let $disassyv := $d/disassyv
        let $info := $d/infoCode
        let $infov := $d/infov
        let $itemloc := $d/itemloc
        let $tname := $d/tname
        let $iname := $d/iname
        return xslt:transform($newD,$style, map {"outputDir":"file:///G:/LMA-Conv/Flight/test-conv-out", "model":$model, "sysDiff":$sdc, "sys":$sys, "subsys":$subsys, "subsubsys":$subsubsys, "assy":$assy, "disassy":$disassy, "disassyv":$disassyv, "info":$info, "infov":$infov, "itemloc":$itemloc, "tname":$tname, "iname":$iname})

名为 Book1-test.xml 的文档本质上是现有元素 ID 到新输出文件名的映射。创建第一个 XML 输出文件后,BaseX 返回 ERROR [FODC0002] ""(第 1 行):文件过早结束。当我在 BaseX 文档中查找错误代码时,此错误被定义为 “无法检索指定的文档资源。”。在循环中使用 xslt:transform 函数是否有一些限制?我不明白为什么它第一次能够检索到,但在那之后就不行了。我试图将 XSL 移动到不同的文件位置,但没有成功。我在这里遗漏了一些非常明显的东西吗?

【问题讨论】:

  • 这可能是一个错误,我认为所需的方法是在 BaseX 邮件列表上要求确认,然后他们在 github.com/BaseXdb/basex 上打开一个问题。对于您拥有的简单样式表(您只需使用从 XQuery 传入的参数填充一些结果元素),您当然应该能够在没有 XSLT 的情况下使用 fn:putdocs.basex.org/wiki/File_Module 在 XQuery (&lt;dmCode modelIdentCode="{$model}" systemDiffCode="{$sysDiff}" systemCode="{$sys}"&gt;) 中执行这些操作写文件。
  • 这只是 XSLT 的开始,从 BaseX DB ($newD) 中提取的节点将被转换为新文件的内容。我正在使用这个简单的开始来降低并开始这个过程。我可能会采用文件模块方法并在 DB 环境之外执行 XSLT。
  • BaseX 修复错误的速度相当快,因此如果您告诉他们问题所在,您可能会在几天或更短的时间内获得修复的新快照。
  • 请注意,有一个奇怪之处,您的样式表与 / 匹配,这将是一个文档节点,但您传入了一个元素节点 $newD,因此您的样式表可能无法达到您的预期。跨度>
  • 它创建的单一输出是我对这个最小开始的预期。我的想法是,在检索 BaseX 中的每个节点时,每个结果都被视为独立文档,我正在转换一个新的独立文档。我成功查询了所有 325 个结果并将其保存到单独的文档中,我可能只是针对这些结果运行 XSL,而不是通过 BaseX。

标签: xml xslt xquery basex


【解决方案1】:

我认为 BaseX 邮件列表上的 Gerrit Imsieke 有正确的解释,BaseX 不会无法处理 XSLT 的第二个输入,它无法将您第一次调用 xslt:transform 的空结果转换为它的任何 XQuery申述。因此,使用 xslt:transform-text 应该可以解决您的问题。或者让 XSLT 输出带有根元素的主要结果。

【讨论】:

  • 使用 xslt:transform-text() 函数就可以了。谢谢你的帮助马丁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 2016-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多