XSLT 按节点值与每个兄弟节点分组

问题描述 投票:0回答:1

我最近开始学习 xslt,我面临以下任务。

stackoverflow上有很多类似的问题,但是都没有考虑需要把一个值放在小写的情况

这是我的输入 XML。我尝试将 meltNum 值放入 节点。

<meltChem>
   <meltNum>301996</meltNum>
   <chem>
      <elemCode>1</elemCode>
      <value>0.052</value>
   </chem>
   <chem>
      <elemCode>2</elemCode>
      <value>0.003</value>
   </chem>
   <chem>
      <elemCode>3</elemCode>
      <value>0.0002</value>
   </chem>
   </meltChem>
   <meltChem>
   <meltNum>99999</meltNum>
   <chem>
      <elemCode>4</elemCode>
      <value>0.052</value>
   </chem>
   <chem>
      <elemCode>5</elemCode>
      <value>0.003</value>
   </chem>
</meltChem>

我不知道如何获取这样的xml:

<meltChem>
   <chem>
   <meltNum>301996</meltNum>
      <elemCode>1</elemCode>
      <value>0.052</value>
   </chem>
   <chem>
   <meltNum>301996</meltNum>
      <elemCode>2</elemCode>
      <value>0.003</value>
   </chem>
   <chem>
   <meltNum>301996</meltNum>
      <elemCode>3</elemCode>
      <value>0.0002</value>
   </chem>
</meltChem>
<meltChem>
   <chem>
   <meltNum>99999</meltNum>
      <elemCode>4</elemCode>
      <value>0.052</value>
   </chem>
   <chem>
   <meltNum>99999</meltNum>
      <elemCode>5</elemCode>
      <value>0.003</value>
   </chem>
</meltChem>

我正在尝试使用一些堆栈溢出解决方案来解决同样的问题,但我得到了重复的节点。

<xsl:for-each select="//docChem/meltChem[generate-id() = generate-id(key('a', meltNum)[1])]">
    <meltNum>
    <xsl:value-of select="meltNum"/>
    </meltNum>
    <xsl:for-each select="key('a', meltNum)">
    <elemCode>
        <xsl:copy-of select="//elemCode"/>
    </elemCode>
    </xsl:for-each>   
</xsl:for-each>

然后我得到了

 <meltNum>В301996</meltNum>
        <elemCode>
          <elemCode>1</elemCode>
          <elemCode>2</elemCode>
          <elemCode>3</elemCode>
          <elemCode>4</elemCode>
          <elemCode>5</elemCode>
        </elemCode>
        <meltNum>99999</meltNum>
        <elemCode>
          <elemCode>1</elemCode>
          <elemCode>2</elemCode>
          <elemCode>3</elemCode>
          <elemCode>4</elemCode>
          <elemCode>5</elemCode>
        </elemCode>
xml xslt-1.0
1个回答
0
投票

请尝试以下解决方案。

它正在使用所谓的Identity Transform模式。

我添加了一个根元素以使 XML 格式正确。

输入 XML

<?xml version="1.0"?>
<root>
    <meltChem>
        <meltNum>301996</meltNum>
        <chem>
            <elemCode>1</elemCode>
            <value>0.052</value>
        </chem>
        <chem>
            <elemCode>2</elemCode>
            <value>0.003</value>
        </chem>
        <chem>
            <elemCode>3</elemCode>
            <value>0.0002</value>
        </chem>
    </meltChem>
    <meltChem>
        <meltNum>99999</meltNum>
        <chem>
            <elemCode>4</elemCode>
            <value>0.052</value>
        </chem>
        <chem>
            <elemCode>5</elemCode>
            <value>0.003</value>
        </chem>
    </meltChem>
</root>

XSLT#1

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

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

    <xsl:template match="chem">
        <xsl:copy>
            <!--<xsl:copy-of select="../meltNum"/>-->
            <xsl:copy-of select="preceding-sibling::meltNum"/>
            <xsl:copy-of select="*"/>
        </xsl:copy>
    </xsl:template>

    <!--remove meltNum element-->
    <xsl:template match="meltNum"/>
</xsl:stylesheet>

XSLT#2

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

    <xsl:template match="/root">
        <xsl:copy>
            <xsl:for-each select="meltChem">
                <xsl:copy>
                    <xsl:variable name="meltNum">
                        <xsl:copy-of select="meltNum"/>
                    </xsl:variable>
                    <xsl:for-each select="chem">
                        <xsl:copy>
                            <xsl:copy-of select="$meltNum"/>
                            <xsl:copy-of select="*"/>
                        </xsl:copy>
                    </xsl:for-each>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出

<?xml version='1.0' ?>
<root>
  <meltChem>
    <chem>
      <meltNum>301996</meltNum>
      <elemCode>1</elemCode>
      <value>0.052</value>
    </chem>
    <chem>
      <meltNum>301996</meltNum>
      <elemCode>2</elemCode>
      <value>0.003</value>
    </chem>
    <chem>
      <meltNum>301996</meltNum>
      <elemCode>3</elemCode>
      <value>0.0002</value>
    </chem>
  </meltChem>
  <meltChem>
    <chem>
      <meltNum>99999</meltNum>
      <elemCode>4</elemCode>
      <value>0.052</value>
    </chem>
    <chem>
      <meltNum>99999</meltNum>
      <elemCode>5</elemCode>
      <value>0.003</value>
    </chem>
  </meltChem>
</root>
© www.soinside.com 2019 - 2024. All rights reserved.