关于xml:在XSLT中插入与子级相同级别的字段

Insert fields on same level as child in XSLT

我还在学习XSLT。我需要帮助将字段作为子项插入订单项节点。字段节点需要插入到之前发生的LineItem中。
在XSLT 1.0中有没有办法解决这个问题?即同级?

之前的xpath轴

传入XML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<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>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<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>