根据条件复制除某些分支之外的完整XML树

时间:2015-11-16 08:51:36

标签: xml xslt

我有一份可能包含零件的零件清单。实际上是物料清单(BOM)。有些部件有一个元件,可以将它们标识为&#34;备件&#34;。当我转换成另一个XML文件时,我只对包含&#34;备件&#34;的节点(和祖先)感兴趣,换句话说<Spare_part_indicator>但是维护该特定节点中的所有兄弟节点同样。 这里我的样本BOM为XML:

    <Level levelNo="1">
        <Component_number>HEKT109476R4</Component_number>
        <Object_description>KEY INTERLOCK</Object_description>
        <Level levelNo="2">
            <Component_number>HENS434350</Component_number>
            <Object_description>LOCK BARREL (PLACEHOLDER)</Object_description>
        </Level>
        <Level levelNo="2">
            <Component_number>HEKT460536P3</Component_number>
            <Object_description>SWITCH_SEC:_PSEN ME1S/1AR_2O/2S</Object_description>
            <Spare_part_indicator>2</Spare_part_indicator>
            <Sort_String>S420</Sort_String>
            <QR_code>HEKT460536P3.png</QR_code>
        </Level>
        <Level levelNo="2">
            <Component_number>HEKT460751R2</Component_number>
            <Object_description>SHEET METAL</Object_description>
            <Level levelNo="3">
                <Component_number>HEKT323873P1</Component_number>
                <Object_description>C-PAN</Object_description>
            </Level>
            <Level levelNo="3">
                <Component_number>HEKT453450P5</Component_number>
                <Object_description>HIGH VOLTAGE CAPACITOR 5NF/30KV 10%</Object_description>
                <Spare_part_indicator>3</Spare_part_indicator>
                <QR_code>HEKT453450P5.png</QR_code>
            </Level>
        </Level>
    </Level>
    <Level levelNo="1">
        <Component_number>HEKT109444R3</Component_number>
        <Object_description>FILTER NETWORK 500KW</Object_description>
        <Level levelNo="2">
            <Component_number>HEKT457790P1</Component_number>
            <Object_description>BRACKET</Object_description>
        </Level>
        <Level levelNo="2">
            <Component_number>HEKT323840P1</Component_number>
            <Object_description>COIL</Object_description>
            <Spare_part_indicator>3</Spare_part_indicator>
            <Sort_String>L401</Sort_String>
            <QR_code>HEKT323840P1.png</QR_code>
        </Level>
    </Level>

现在我想将上面的列表转换为一个新的XML树,其中只包含具有元素<Spare_part_indicator>但保持层次结构的节点,包括祖先。我遇到了以下XSL样式表,经过一些修改后,它完全符合我的要求。但不幸的是,它只留下了<Spare_part_indicator>元素,并删除了所有其他元素,如Component_number等。

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="subSelectionXPath"
  select="//Spare_part_indicator"
  />

 <xsl:template match="*">
  <xsl:choose>
   <xsl:when test=
   "descendant::node()
        [count(.|$subSelectionXPath)
        =
         count($subSelectionXPath)
        ]
   ">
   <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="*"/>
   </xsl:copy>
  </xsl:when>

   <xsl:when test=
   "count(.|$subSelectionXPath)
   =
    count($subSelectionXPath)
   ">
   <xsl:copy-of select="."/>

   </xsl:when>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

上述BOM的预期结果如下:

<Level levelNo="1">
    <Component_number>HEKT109476R4</Component_number>
    <Object_description>KEY INTERLOCK</Object_description>
    <Level levelNo="2">
        <Component_number>HEKT460536P3</Component_number>
        <Object_description>SWITCH_SEC:_PSEN ME1S/1AR_2O/2S</Object_description>
        <Spare_part_indicator>2</Spare_part_indicator>
        <Sort_String>S420</Sort_String>
        <QR_code>HEKT460536P3.png</QR_code>
    </Level>
    <Level levelNo="2">
        <Component_number>HEKT460751R2</Component_number>
        <Object_description>SHEET METAL</Object_description>
        <Level levelNo="3">
            <Component_number>HEKT453450P5</Component_number>
            <Object_description>HIGH VOLTAGE CAPACITOR 5NF/30KV 10%</Object_description>
            <Spare_part_indicator>3</Spare_part_indicator>
            <QR_code>HEKT453450P5.png</QR_code>
        </Level>
    </Level>
</Level>
<Level levelNo="1">
    <Component_number>HEKT109444R3</Component_number>
    <Object_description>FILTER NETWORK 500KW</Object_description>
    <Level levelNo="2">
        <Component_number>HEKT323840P1</Component_number>
        <Object_description>COIL</Object_description>
        <Spare_part_indicator>3</Spare_part_indicator>
        <Sort_String>L401</Sort_String>
        <QR_code>HEKT323840P1.png</QR_code>
    </Level>
</Level>

到目前为止,我无法弄清楚,我如何能够保留兄弟元素,以及父节点中的元素以及此处的提示,我们将非常感激。 我希望我能正确描述问题,请耐心等待,因为我才开始发现XSL stlyesheets的强大功能。

1 个答案:

答案 0 :(得分:0)

唔...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>

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

  <!-- except levels without Spare_part_indicator anywhere inside -->
  <xsl:template match="Level[not(.//Spare_part_indicator)]"/>

</xsl:stylesheet>