英文:
XSLT grouping by node value with each siblings
问题
以下是您提供的内容的中文翻译:
我最近开始学习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>
我试图使用一些stackoverflow上与同一问题相关的解决方案,但我得到了节点的重复。
<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>
英文:
I started learning xslt quite recently and I was faced with the following task.
There are many similar questions on stackoverflow, but none of them considers the case when you need to put a value in a lower case
This my input XML. I try to put meltNum value into <chem> node.
<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>
I don't know how to get xml like this:
<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>
I'm trying to use some stack overflow solution with same problem, but I'am getting duplication of nodes.
<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>
and then i got
 <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>
答案1
得分: 0
请尝试以下解决方案。
它使用了所谓的“身份变换”模式。
我添加了一个根元素,使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="*"/>
    <!--身份变换模式-->
    <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>
    <!--移除meltNum元素-->
    <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>
英文:
Please try the following solution.
It is using a so called Identity Transform pattern.
I added a root element to make XML well-formed.
Input 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>
Output
<?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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论