在 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>
我仍在学习 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>