0

在输入 XML 文件中,除了静态列之外,期望来自其他文件(参考)的数据的列也是可用的。但是对于每个引用,输入 xml 都有具有相同 ID 或 UID 的单独行。

输出文件必须在一行中包含所有引用和关系(基于 ID 或 UID)

我也为这个转换编写了 XSLT。当行数较少(< 100 或 < 200)时,此 XSLT 会更快。但是,随着计数的增加,输出 xml 生成需要很长时间(对于 1000 行的计数,大约需要 30 分钟)。

我在用

<xsl:for-each select="z:row/@ID[generate-id() = generate-id(key('UniqueID',.))]">

在 XSLT 中。因为对于输入 xml 的每一行中的相同 ID,它必须检查多个引用(如部分)和关系(如子级)并填充与列相同

输入原始 XML 文件。

<xml xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:z="#RowsetSchema">
<rs:data>
    <z:row UID="PARENT_001_1221AD_A878" GroupID="" GroupRel="" ID="37" Name="Outer Asset Details" RelProduct="Line1" RelUID="CHILD1_101_9899_9POOU99" RelName="CHILD1" RelType="Child" Size="22"/>
    <z:row UID="PARENT_001_1221AD_A878" GroupID="" GroupRel="" ID="37" Name="Outer Asset Details" RelProduct="Line1" RelUID="CHILD2_201_5646546_9890PBS" RelName="CHILD1" RelType="Child" Size="22"/>
    <z:row UID="PARENT_001_1221AD_A878" GroupID="" GroupRel="" ID="37" Name="Outer Asset Details" RelProduct="Line1" RelUID="SEC_999_99565_998AFSD" RelName="Hydraulic Section" RelType="Section" Size="22"/>
</rs:data>

子.xml

<Child xsi:noNamespaceSchemaLocation="../XSD/Child.xsd" FILE="Child" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Row UID="CHILD1_101_9899_9POOU99">
    <Name>CHILD1</Name>
    <Description>This has details about the Hydraulic sections of the automobile</Description>
</Row>
<Row UID="CHILD2_201_5646546_9890PBS">
    <Name>CHILD2</Name>
    <Description>This has details about the manual sections of the automobile</Description>
</Row>

节.xml

<Section xsi:noNamespaceSchemaLocation="../XSD/Section.xsd" FILE="Section" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Row UID="SEC_999_99565_998AFSD">
    <Name>Hydraulic Section</Name>
    <Description>This has details about the Sections in which the Hydraulic Systems are used.</Description>
</Row>

XSLT 文件

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" exclude-result-prefixes="s dt z rs msxsl" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="UniqueID" match="z:row/@ID" use="."/>
<xsl:template match="/">
    <Parent xsi:noNamespaceSchemaLocation="../XSD/Parent.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" FILE="Parent">
        <xsl:for-each select="xml">
            <xsl:apply-templates select="rs:data"/>
        </xsl:for-each>
    </Parent>
</xsl:template>
<xsl:template match="rs:data">
    <xsl:for-each select="z:row/@ID[generate-id() = generate-id(key('UniqueID',.))]">
        <xsl:variable name="FRId">
            <xsl:value-of select="current()"/>
        </xsl:variable>
        <xsl:variable name="curNSet" select="//z:row[@ID=$FRId]"/>
        <xsl:copy-of select="current()"/>
        <Record>
            <xsl:attribute name="UID"><xsl:value-of select="$curNSet/@UID"/></xsl:attribute>
            <xsl:element name="Size">
                <xsl:value-of select="$curNSet/@Size"/>
            </xsl:element>
            <xsl:element name="Child">
                <xsl:apply-templates select="$curNSet[@RelType='Child']" mode="Relations">
                    <xsl:with-param name="RelType" select="'Child'"/>
                    <xsl:with-param name="DstFileName" select="'../Files/Child.xml'"/>
                </xsl:apply-templates>
            </xsl:element>
            <xsl:element name="Section">
                <xsl:apply-templates select="$curNSet[@RelType='Section']" mode="References">
                    <xsl:with-param name="RelType" select="'Section'"/>
                    <xsl:with-param name="DstFileName" select="'../Files/Section.xml'"/>
                </xsl:apply-templates>
            </xsl:element>
        </Record>
    </xsl:for-each>
</xsl:template>
<xsl:template match="z:row" mode="Relations">
    <xsl:param name="RelType"/>
    <xsl:param name="DstFileName"/>
    <xsl:element name="{$RelType}">
        <xsl:attribute name="DestinationKey"><xsl:value-of select="@RelUID"/></xsl:attribute>
        <xsl:attribute name="RelFilePath"><xsl:value-of select="$DstFileName"/></xsl:attribute>
        <xsl:attribute name="SequenceNumber"><xsl:value-of select="position()"/></xsl:attribute>
        <xsl:value-of select="@RelName"/>
    </xsl:element>
</xsl:template>
<xsl:template match="z:row" mode="References">
    <xsl:param name="DstFileName"/>
    <xsl:attribute name="DestinationKey"><xsl:value-of select="@RelUID"/></xsl:attribute>
    <xsl:attribute name="RelFilePath"><xsl:value-of select="$DstFileName"/></xsl:attribute>
    <xsl:attribute name="SequenceNumber"><xsl:value-of select="position()"/></xsl:attribute>
    <xsl:value-of select="@RelName"/>
</xsl:template>

输出.xml

<Parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../XSD/Parent.xsd" FILE="Parent" ID="37">
<Record UID="PARENT_001_1221AD_A878">
    <Size>22</Size>
    <Child>
        <Child DestinationKey="CHILD1_101_9899_9POOU99" RelFilePath="../Files/Child.xml" SequenceNumber="1">CHILD1</Child>
        <Child DestinationKey="CHILD2_201_5646546_9890PBS" RelFilePath="../Files/Child.xml" SequenceNumber="2">CHILD1</Child>
    </Child>
    <Section DestinationKey="SEC_999_99565_998AFSD" RelFilePath="../Files/Section.xml" SequenceNumber="1">Hydraulic Section</Section>
</Record>

请帮助我优化 XSLT,以便更快地生成输出文件

4

1 回答 1

1

考虑使用

<xsl:key name="UniqueID" match="z:row" use="@ID"/>

然后

<xsl:for-each select="z:row/@ID[generate-id() = generate-id(key('UniqueID',.))]">
        <xsl:variable name="FRId">
            <xsl:value-of select="current()"/>
        </xsl:variable>
        <xsl:variable name="curNSet" select="//z:row[@ID=$FRId]"/>

可以替换为

<xsl:for-each select="z:row[generate-id() = generate-id(key('UniqueID', @ID))]">
        <xsl:variable name="FRId" select="@ID"/>

        <xsl:variable name="curNSet" select="key('UniqueID', @ID"/>

我不确定您是否需要该变量FRId,但使用select属性而不是嵌套定义它value-of肯定会消耗更少的资源。

 <xsl:apply-templates select="$curNSet[@RelType='Child']" mode="Relations">

更有效地定义一个键

<xsl:key name="rel" match="z:row" use="concat(@ID, '|', @RelType)"/>

然后使用

 <xsl:apply-templates select="key('rel', concat(@ID, '|', 'Child')" mode="Relations">

然后对其他应用模板使用相同的方法。

以上所有内容都未经测试,但应该给你一个想法。

于 2013-08-08T10:59:10.270 回答