如何根据条件匹配移动XML元素

时间:2016-10-14 06:15:24

标签: xslt xslt-1.0 xslt-2.0

我有一个XML:

<?xml version="1.0" encoding="UTF-8"?>
<COLLECTION>
<AddedBOMs NAME="AddedBOMs" TYPE="Unknown" STATUS="0">
<BOMHeader>
    <Number>One</Number>
    <StartEffectivity>One 00:00:00</StartEffectivity>
    <EndEffectivity>One 00:00:00</EndEffectivity>
</BOMHeader>
</AddedBOMs>
<ChangedBOMs NAME="ChangedBOMs" TYPE="Unknown" STATUS="0">
<BOMHeader>
    <Number>Two</Number>
    <StartEffectivity>Two 00:00:00</StartEffectivity>
    <EndEffectivity>Two 00:00:00</EndEffectivity>
</BOMHeader>
</ChangedBOMs>
<UnchangedBOMs NAME="UnchangedBOMs" TYPE="Unknown" STATUS="0">
<BOMHeader>
    <Number>Three</Number>
    <StartEffectivity>Three 00:00:00</StartEffectivity>
    <EndEffectivity>Three 00:00:00</EndEffectivity>
</BOMHeader>
</UnchangedBOMs>
<DeletedBOMComponents NAME="DeletedBOMComponents" TYPE="Unknown" STATUS="0">
<BOMComponent>
    <PartNumber>Three</PartNumber>
</BOMComponent>
</DeletedBOMComponents>
<AddedBOMComponents NAME="AddedBOMComponents" TYPE="Unknown" STATUS="0">
<BOMComponent>
    <PartNumber>One</PartNumber>
</BOMComponent>
</AddedBOMComponents>
<ChangedBOMComponents NAME="ChangedBOMComponents" TYPE="Unknown" STATUS="0">
<BOMComponent>
    <PartNumber>Two</PartNumber>
</BOMComponent>
</ChangedBOMComponents>
</COLLECTION>

预期的输出就像。

<?xml version="1.0" encoding="UTF-8"?>
<COLLECTION>
<AddedBOMs NAME="AddedBOMs" TYPE="Unknown" STATUS="0">
<BOMHeader>
    <Number>One</Number>
    <StartEffectivity>One 00:00:00</StartEffectivity>
    <EndEffectivity>One 00:00:00</EndEffectivity>
</BOMHeader>
</AddedBOMs>
<ChangedBOMs NAME="ChangedBOMs" TYPE="Unknown" STATUS="0">
<BOMHeader>
    <Number>Two</Number>
    <StartEffectivity>Two 00:00:00</StartEffectivity>
    <EndEffectivity>Two 00:00:00</EndEffectivity>
</BOMHeader>
</ChangedBOMs>
<UnchangedBOMs NAME="UnchangedBOMs" TYPE="Unknown" STATUS="0">
<BOMHeader>
    <Number>Three</Number>
    <StartEffectivity>Three 00:00:00</StartEffectivity>
    <EndEffectivity>Three 00:00:00</EndEffectivity>
</BOMHeader>
</UnchangedBOMs>
<DeletedBOMComponents NAME="DeletedBOMComponents" TYPE="Unknown" STATUS="0">
<BOMComponent>
    <PartNumber>Three</PartNumber>
    <StartEffectivity>--</StartEffectivity>
    <EndEffectivity>Three 00:00:00</EndEffectivity>
</BOMComponent>
</DeletedBOMComponents>
<AddedBOMComponents NAME="AddedBOMComponents" TYPE="Unknown" STATUS="0">
<BOMComponent>
    <PartNumber>One</PartNumber>
    <StartEffectivity>One 00:00:00</StartEffectivity>
    <EndEffectivity>One 00:00:00</EndEffectivity>
</BOMComponent>
</AddedBOMComponents>
<ChangedBOMComponents NAME="ChangedBOMComponents" TYPE="Unknown" STATUS="0">
<BOMComponent>
    <PartNumber>Two</PartNumber>
    <StartEffectivity>Two 00:00:00</StartEffectivity>
    <EndEffectivity>Two 00:00:00</EndEffectivity>
</BOMComponent>
</ChangedBOMComponents>
</COLLECTION>

AddedBOMs 将移至 AddedBOMComponents 并因此全部移动并不固定。它取决于来自 BOMComponent PartNumber 和来自 BOMHeader 数量 StartEffectivity匹配的人 EndEffectivity 需要移动。

如果中的已删除的BOM组件/ BOM组件 “活动” BOM组件需要保持为空且 StartEffectivity 来自 BOMHeader 将在 BOMComponent

中变为 EndEffectivity

为此,我制作了一个XSL文件,但它无法正常工作。

<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:template match= "@*|node()" >
    <xsl:copy>
        <xsl:apply-templates select= "@*|node()" />
    </xsl:copy>
</xsl:template >
       <xsl:template match="BOMComponent/PartNumber">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
       <start><xsl:apply-templates
            select="../../BOMHeader[Number = current()]/StartEffectivity" mode="move"/></start> 
            <end><xsl:apply-templates
            select="../../BOMHeader[Number = current()]/EndEffectivity" mode="move"/></end>
    </xsl:template>
</xsl:stylesheet>

请建议:

1 个答案:

答案 0 :(得分:0)

AFAICT,你想做:

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="header" match="BOMHeader" use="Number" />

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

<xsl:template match="BOMComponent">
    <xsl:variable name="head" select="key('header', PartNumber)" />
    <xsl:copy>
        <xsl:copy-of select="PartNumber"/>
        <xsl:copy-of select="$head/StartEffectivity | $head/EndEffectivity"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="DeletedBOMComponents/BOMComponent">
    <xsl:copy>
        <xsl:copy-of select="PartNumber"/>
        <StartEffectivity>--</StartEffectivity>
        <EndEffectivity>
            <xsl:value-of select="key('header', PartNumber)/StartEffectivity" />
        </EndEffectivity>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>