【问题标题】:Problem splitting XML into multiple files using XSLT使用 XSLT 将 XML 拆分为多个文件的问题
【发布时间】:2020-05-11 16:21:31
【问题描述】:

我正在尝试创建一个 XSL 转换,它将 XML 文档拆分为多个符合相同架构的文件。我遇到的问题是我的 XSLT 输出一个包含内容但没有 XML 标记的文件。我在这个论坛上读过类似的帖子,但我似乎无法解决这个问题。下面是我的源 XML 和 XSLT 示例。

任何建议将不胜感激。

源 XML 示例:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<inm:Results productTitle="Inmagic DB/TextWorks" productVersion="17.0" xmlns:inm="http://www.inmagic.com/webpublisher/query">
<inm:Recordset setCount="4">
<inm:Record setEntry="0">
<inm:Title>Portraits</inm:Title>
<inm:DateRange>[ca. 1955]-[ca. 1973]</inm:DateRange>
<inm:FondsNo>18</inm:FondsNo>
<inm:SeriesNo>1</inm:SeriesNo>
<inm:FileNo />
<inm:ItemNo />
<inm:AccessionNo>2005-2-1</inm:AccessionNo>
<inm:AcquisitionSource />
<inm:CustodialHistory />
</inm:Record>
<inm:Record setEntry="1">
<inm:Title>John Smith</inm:Title>
<inm:DateRange>[ca. 1960]</inm:DateRange>
<inm:FondsNo>18</inm:FondsNo>
<inm:SeriesNo>1</inm:SeriesNo>
<inm:FileNo />
<inm:ItemNo>1</inm:ItemNo>
<inm:AccessionNo />
<inm:AcquisitionSource />
<inm:CustodialHistory />
</inm:Record>
<inm:Record setEntry="2">
<inm:Title>John and Danielle Smith</inm:Title>
<inm:DateRange>[ca. 1965]</inm:DateRange>
<inm:FondsNo>18</inm:FondsNo>
<inm:SeriesNo>1</inm:SeriesNo>
<inm:FileNo />
<inm:ItemNo>2</inm:ItemNo>
<inm:AccessionNo />
<inm:AcquisitionSource />
<inm:CustodialHistory />
</inm:Record>
<inm:Record setEntry="3">
<inm:Title>Luke Smith</inm:Title>
<inm:DateRange>[ca. 1960]</inm:DateRange>
<inm:FondsNo>18</inm:FondsNo>
<inm:SeriesNo>1</inm:SeriesNo>
<inm:FileNo />
<inm:ItemNo>3</inm:ItemNo>
<inm:AccessionNo />
<inm:AcquisitionSource />
<inm:CustodialHistory />
</inm:Record>
</inm:Recordset>
</inm:Results>

我希望在单独的文件中包含记录标签中的内容。

还有我的 XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:inm="http://www.inmagic.com/webpublisher/query">

<xsl:output name="xml" method="xml" indent="yes"/>
<xsl:template match="/">
  <xsl:for-each select="/Results/Recordset/Record">
    <xsl:result-document method="xml" href="file_{@setEntry}-output.xml">
      <Record>
        <xsl:copy-of select="/Record/@*" />
      </Record>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template> 
</xsl:stylesheet>

我正在使用 Saxon 并使用 Power Shell 命令执行它。

【问题讨论】:

  • 您使用的是哪个版本的 Saxon,您在 PowerShell 中使用的是哪个命令?
  • 我使用的是 Saxon 9 HE,Power Shell 命令是PS C:\Users\David\Desktop\XSLT_Test&gt; java -jar c:\saxon\saxon9he.jar -s:Input -xsl:Split4.xsl -o:Output
  • 在 Saxon 10 中有一个新的命令行开关来选择命名空间中的元素,否则使用 xpath-default-namespace 或您声明的前缀。目前尚不清楚单个文件的确切外观。
  • 当我添加前缀时,它会创建单独的文件(所以在那里进行),但它们都是空的 - 没有内容,没有标记。我错过了什么?
  • 如果您编辑您的问题并显示当前代码和您想要的结果以及您得到的结果,我们会更容易。如果创建了文件,我猜它们至少包含一个空的 &lt;Record/&gt; 元素; &lt;xsl:copy-of select="/Record/@*" /&gt; 有点奇怪,因为它似乎根本没有属性,当然在 for-each 内部,上下文节点是当前处理的 Record,所以你要么不需要文字 Record你输出但只是简单地做&lt;xsl:copy-of select="."/&gt;,或者你用&lt;xsl:copy-of select="node()"/&gt;复制孩子。

标签: xml xslt


【解决方案1】:

首先,您没有使用命名空间引用您的节点。 你应该像这样使用它:

<xsl:for-each select="inm:Results/inm:Recordset/inm:Record">

第二件事,在你的代码中你试图复制记录属性

<xsl:copy-of select="/Record/@*" />

但您的上下文已经是一个记录。因此,您应该只使用 @* 选择属性,或者为了更清楚,您可以简单地将 Record 中的唯一属性命名为 @setEntry。

【讨论】:

    【解决方案2】:

    谢谢你们,马丁和塞巴斯蒂安! XSLT 工作正常,我对输出文件很满意。按照大家的建议,最终的 XSLT 是这样的:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:inm="http://www.inmagic.com/webpublisher/query">
    
    <xsl:output name="xml" method="xml" indent="yes"/>
    <xsl:template match="/">
      <xsl:for-each select="/inm:Results/inm:Recordset/inm:Record">
        <xsl:result-document method="xml" href="file_{@setEntry}-output.xml">
            <inm:Record>
            <xsl:copy-of select="node()"/>
            </inm:Record>
        </xsl:result-document>
      </xsl:for-each>
    </xsl:template> 
    </xsl:stylesheet>
    

    【讨论】:

    • 不客气。如果您的问题得到解答,请接受答案并将其标记为已关闭。
    猜你喜欢
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多