xslt - 通过 XSLT 提取和移动节点

标签 xslt

我需要转换传入的 XML,以便可以提取“类别”等于“二”的所有“项目”,并将它们移动到一个单独的“记录”节点,其属性初始化为 type="two"。

这是传入 XML 的示例。

<datafeed>
<records type="one">
    <purchases>
    <items>
            <item>
                <categorie>one</categorie>
                <intrant>String</intrant>
            </item>
            <item>
                <categorie>two</categorie>
                <intrant>String</intrant>
            </item>
            <item>
                <categorie>one</categorie>
                <intrant>String</intrant>
            </item>
            <item>
                <categorie>two</categorie>
                <intrant>String</intrant>
            </item>                         
        </items>
    </purchases>
    </records>
<exchange/>
<context/>
<pilotage/>
</datafeed>

这就是我想要的:

<datafeed>
<records type="one">
    <purchases>
    <items>
            <item>
                <categorie>one</categorie>
                <intrant>String</intrant>
            </item>
            <item>
                <categorie>one</categorie>
                <intrant>String</intrant>
            </item>                 
        </items>
    </purchases>
    </records>
  <records type="two">
    <purchases>
    <items>
            <item>
                <categorie>two</categorie>
                <intrant>String</intrant>
            </item>
            <item>
                <categorie>two</categorie>
                <intrant>String</intrant>
            </item>                         
        </items>
    </purchases>
    </records>
<exchange/>
<context/>
<pilotage/>
</datafeed>

我现在有两个“记录”都使用其预定义类型(始终是一个或两个)进行初始化。提取的记录已被移动,因此从原始记录中删除。

谢谢

最佳答案

这种转变:

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

 <xsl:key name="kitemByCategory" match="item"
  use="categorie"/>

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

 <xsl:template match="records">
  <xsl:call-template name="identity"/>

  <xsl:variable name="vCat2Items" select=
   "key('kitemByCategory', 'two')"/>

  <xsl:if test="$vCat2Items">
    <records type="two">
        <purchases>
          <items>
            <xsl:copy-of select="$vCat2Items"/>
          </items>
        </purchases>
    </records>
  </xsl:if>
 </xsl:template>

 <xsl:template match="item[categorie = 'two']"/>
</xsl:stylesheet>

当应用于提供的 XML 文档时,会产生所需的正确结果:

<datafeed>
   <records type="one">
      <purchases>
         <items>
            <item>
               <categorie>one</categorie>
               <intrant>String</intrant>
            </item>
            <item>
               <categorie>one</categorie>
               <intrant>String</intrant>
            </item>
         </items>
      </purchases>
   </records>
   <records type="two">
      <purchases>
         <items>
            <item>
               <categorie>two</categorie>
               <intrant>String</intrant>
            </item>
            <item>
               <categorie>two</categorie>
               <intrant>String</intrant>
            </item>
         </items>
      </purchases>
   </records>
   <exchange/>
   <context/>
   <pilotage/>
</datafeed>

请注意:

  1. 身份规则的使用和覆盖

  2. 如何通过使用匹配类别“two”的空模板将其排除在处理之外

  3. 使用按键可以按类别高效、方便地定位项目。

关于xslt - 通过 XSLT 提取和移动节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3180641/

相关文章:

c# - 将 Linq 转换为 XSLT

xslt - 将 XHTML 转换为 Word ML

java - 由 : org. xml.sax.SAXParseException 引起:文件过早结束

java - 使用 XSLT 复制 XML 时绕过命名空间

xml - 从xml文件中提取混合数据

xml - 使用 XSL 替换默认命名空间

xml - 使用 XSLT 从 XML 文件中删除所有处理指令

xml - XSLT:除特定类型之外的所有深度的最后一个元素

xml - XSLT:检查是否有任何一组元素具有具有指定值的子元素

xslt - 寻找(伪)XSLT 预处理器/模板器以使其不那么冗长