Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从一个XML文件到另一个XML文件获取不断增加的ID_Xml_Xslt_Ssis - Fatal编程技术网

从一个XML文件到另一个XML文件获取不断增加的ID

从一个XML文件到另一个XML文件获取不断增加的ID,xml,xslt,ssis,Xml,Xslt,Ssis,一般来说,我有以下情况: 一个数据库由3000个文件组成。每个文件平均由500个结构相同的节点组成。每个节点的顶级父元素“Document”具有唯一的ID(非数字) 任务: 文档及其节点中的所有子项/子项必须获得额外的数字ID(递增计数文档节点) ID必须具有可分配的起始范围。ID随步骤+1递增。(如350001、350002等) (问题的本质)ID计数器不仅在一个XML文件级别上继续工作,而且在整个文件集上也继续工作 也许,我认为,我的问题并不意味着我的具体代码,而是要求一个方法模型或一组

一般来说,我有以下情况: 一个数据库由3000个文件组成。每个文件平均由500个结构相同的节点组成。每个节点的顶级父元素“Document”具有唯一的ID(非数字)

任务:

  • 文档及其节点中的所有子项/子项必须获得额外的数字ID(递增计数文档节点)

  • ID必须具有可分配的起始范围。ID随步骤+1递增。(如350001、350002等)

  • (问题的本质)ID计数器不仅在一个XML文件级别上继续工作,而且在整个文件集上也继续工作

也许,我认为,我的问题并不意味着我的具体代码,而是要求一个方法模型或一组抽象模式来解决所描述的情况

  • 我将非常感谢所有建议使用XSLT语言的解决方案

  • 或者,作为替代或补充方式,通过SSIS工具

UPD:感谢Martin Honnen提供3.0解决方案

UPD:此外,如果有任何XSLT1.0解决方案,我将不胜感激


UPD:或者通过xslt 3中的其他集成的非xslt SSIS工具,您可以使用
xsl:iterate
和累加器来完成:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

    <xsl:param name="documents" as="document-node()*">
        <xsl:iterate select="1 to 5">
            <xsl:document>
                <root>
                    <xsl:iterate select="1 to 5">
                        <section>
                            <xsl:iterate select="1 to 20">
                                <foo>foo {.}</foo>
                            </xsl:iterate>
                        </section>
                    </xsl:iterate>
                </root>
            </xsl:document>
        </xsl:iterate>
    </xsl:param>

    <xsl:param name="start-id" as="xs:integer" select="35000"/>

    <xsl:output indent="yes"/>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:accumulator name="element-count" as="xs:integer" initial-value="0">
        <xsl:accumulator-rule match="*" select="$value + 1"/>
    </xsl:accumulator>

    <xsl:template match="/" name="xsl:initial-template">
        <xsl:iterate select="$documents">
            <xsl:param name="start-id" select="$start-id"/>
            <xsl:apply-templates select="node()">
                <xsl:with-param name="start-id" select="$start-id" tunnel="yes"/>
            </xsl:apply-templates>
            <xsl:next-iteration>
                <xsl:with-param name="start-id" select="$start-id + accumulator-after('element-count')"/>
            </xsl:next-iteration>
        </xsl:iterate>
    </xsl:template>

    <xsl:template match="*">
        <xsl:param name="start-id" tunnel="yes"/>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="collection-count" select="$start-id + accumulator-before('element-count')"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
而不是

        <xsl:apply-templates select="node()">
            <xsl:with-param name="start-id" select="$start-id" tunnel="yes"/>
        </xsl:apply-templates>

目前还没有流媒体,因为我目前不确定如何从流媒体文档中传递值,稍后我将查看是否可以解决该问题。但无论如何,流媒体都需要Saxon EE。

那是哪个数据库?它可以使用哪个XSLT处理器?数据库由XML文件组成。但是你可以忽略这是一个数据库,忘记这个词。重要的是,它是一系列XML文件,需要进行大量操作。问题是-在多大程度上这只能在XSLT语言内完成,从一个文件循环到另一个文件。从第1卷到第2卷的任何标准XSLT处理器,或者如果某些解决方案可能仅来自3.0-我将欢迎,并且也是这个变体)谢谢!我将尝试实现此代码。难道你不知道微软的SSIS支持XSLT 3.0吗?微软自己的XSLT处理器,如各种MSXML版本和.NET版本,如XslCompiledTransform,只支持XSLT 1.0。我不知道SSIS是否允许插入XSLT 2或3处理器,如Saxon 9或XmlPrime或Altova Raptor。使用哪种自由软件XSLT工具来处理许多文件(支持3.0)。Saxon 9.9适用于.NET平台(在NuGet和Sourceforge上)和Java平台(在Maven和Sourceforge上)正如Martin Honnen已经指出的,SSIS开箱即用仅支持XSLT v.1.0,尽管SSIS脚本任务允许启动任何.Net代码。所以,结合Saxon 9.9.Net版本和SSIS脚本任务将提供一个解决方案。
  <xsl:result-document href="{document-uri()}-update.xml">
        <xsl:apply-templates select="node()">
            <xsl:with-param name="start-id" select="$start-id" tunnel="yes"/>
        </xsl:apply-templates>
  </xsl:result-document>
        <xsl:apply-templates select="node()">
            <xsl:with-param name="start-id" select="$start-id" tunnel="yes"/>
        </xsl:apply-templates>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" expand-text="yes"
    version="3.0">

    <xsl:param name="input-uris" select="uri-collection('?select=sample-*.xml')"/>

    <xsl:param name="start-id" as="xs:integer" select="35000"/>

    <xsl:mode on-no-match="shallow-copy" streamable="yes" use-accumulators="element-count"/>

    <xsl:accumulator name="element-count" as="xs:integer" initial-value="0" streamable="yes">
        <xsl:accumulator-rule match="*" select="$value + 1"/>
    </xsl:accumulator>

    <xsl:template match="/" name="xsl:initial-template">
        <xsl:iterate select="$input-uris ! doc(.)">
            <xsl:param name="start-id" select="$start-id"/>
            <xsl:result-document href="updated-xmls/{tokenize(document-uri(), '/')[last()]}">
                <xsl:apply-templates select="node()">
                    <xsl:with-param name="start-id" select="$start-id" tunnel="yes"/>
                </xsl:apply-templates>
            </xsl:result-document>
            <xsl:next-iteration>
                <xsl:with-param name="start-id"
                    select="$start-id + accumulator-after('element-count')"/>
            </xsl:next-iteration>
        </xsl:iterate>
    </xsl:template>

    <xsl:template match="*">
        <xsl:param name="start-id" tunnel="yes"/>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="collection-count"
                select="$start-id + accumulator-before('element-count')"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>