在 XSLT 中插入与子级相同级别的字段

Insert fields on same level as child in XSLT

我仍在学习 XSLT。我需要帮助将字段作为子项插入到订单项节点。需要将 Field 节点插入到前面发生的 LineItem 中。 有没有办法在 XSLT 1.0 中处理这个问题?即 xpath 轴在兄弟之前?

传入 XML:

<Data>
<Data>
    <Field1/>
    <Field2/>
    <Field3/>
    <LineItem>
        <LineItemNum>1</LineItemNum>
    </LineItem>
    <Field>
        <HouseNumber/>
    </Field>
    <Field>
        <HouseNumber/>
    </Field>
    <Field>
        <HouseNumber/>
    </Field>
    <LineItem>
        <LineItemNum>2</LineItemNum>
    </LineItem>
    <Field>
        <HouseNumber/>
    </Field>
    <Field>
        <HouseNumber/>
    </Field>
    <Field>
        <HouseNumber/>
    </Field>
</Data>

Output needed:
  <Data>
   <Data>
    <Field1/>
    <Field2/>
    <Field3/>
    <LineItem>
        <LineItemNum>1</LineItemNum>
        <Field>
            <HouseNumber/>
        </Field>
        <Field>
            <HouseNumber/>
        </Field>
        <Field>
            <HouseNumber/>
        </Field>
    </LineItem>
    <LineItem>
        <LineItemNum>2</LineItemNum>
        <Field>
            <HouseNumber/>
        </Field>
        <Field>
            <HouseNumber/>
        </Field>
        <Field>
            <HouseNumber/>
        </Field>
    </LineItem>
</Data>

这远非微不足道,我不会向初学者推荐它。尝试以下方法:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="field-by-item" match="Field" use="generate-id(preceding-sibling::LineItem[1])" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Data/Data">
    <xsl:copy>
        <xsl:apply-templates select="*[not(self::Field)]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="LineItem">
    <xsl:copy>
        <xsl:apply-templates/>
        <xsl:apply-templates select="key('field-by-item', generate-id())"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>