XSLT通过节点值对每个兄弟节点进行分组。

huangapple go评论45阅读模式
英文:

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 &lt;chem&gt; node.

&lt;meltChem&gt;
   &lt;meltNum&gt;301996&lt;/meltNum&gt;
   &lt;chem&gt;
      &lt;elemCode&gt;1&lt;/elemCode&gt;
      &lt;value&gt;0.052&lt;/value&gt;
   &lt;/chem&gt;
   &lt;chem&gt;
      &lt;elemCode&gt;2&lt;/elemCode&gt;
      &lt;value&gt;0.003&lt;/value&gt;
   &lt;/chem&gt;
   &lt;chem&gt;
      &lt;elemCode&gt;3&lt;/elemCode&gt;
      &lt;value&gt;0.0002&lt;/value&gt;
   &lt;/chem&gt;
   &lt;/meltChem&gt;
   &lt;meltChem&gt;
   &lt;meltNum&gt;99999&lt;/meltNum&gt;
   &lt;chem&gt;
      &lt;elemCode&gt;4&lt;/elemCode&gt;
      &lt;value&gt;0.052&lt;/value&gt;
   &lt;/chem&gt;
   &lt;chem&gt;
      &lt;elemCode&gt;5&lt;/elemCode&gt;
      &lt;value&gt;0.003&lt;/value&gt;
   &lt;/chem&gt;
&lt;/meltChem&gt;

I don't know how to get xml like this:

&lt;meltChem&gt;
   &lt;chem&gt;
   &lt;meltNum&gt;301996&lt;/meltNum&gt;
      &lt;elemCode&gt;1&lt;/elemCode&gt;
      &lt;value&gt;0.052&lt;/value&gt;
   &lt;/chem&gt;
   &lt;chem&gt;
   &lt;meltNum&gt;301996&lt;/meltNum&gt;
      &lt;elemCode&gt;2&lt;/elemCode&gt;
      &lt;value&gt;0.003&lt;/value&gt;
   &lt;/chem&gt;
   &lt;chem&gt;
   &lt;meltNum&gt;301996&lt;/meltNum&gt;
      &lt;elemCode&gt;3&lt;/elemCode&gt;
      &lt;value&gt;0.0002&lt;/value&gt;
   &lt;/chem&gt;
&lt;/meltChem&gt;
&lt;meltChem&gt;
   &lt;chem&gt;
   &lt;meltNum&gt;99999&lt;/meltNum&gt;
      &lt;elemCode&gt;4&lt;/elemCode&gt;
      &lt;value&gt;0.052&lt;/value&gt;
   &lt;/chem&gt;
   &lt;chem&gt;
   &lt;meltNum&gt;99999&lt;/meltNum&gt;
      &lt;elemCode&gt;5&lt;/elemCode&gt;
      &lt;value&gt;0.003&lt;/value&gt;
   &lt;/chem&gt;
&lt;/meltChem&gt;

I'm trying to use some stack overflow solution with same problem, but I'am getting duplication of nodes.

&lt;xsl:for-each select=&quot;//docChem/meltChem[generate-id() = generate-id(key(&#39;a&#39;, meltNum)[1])]&quot;&gt;
	&lt;meltNum&gt;
	&lt;xsl:value-of select=&quot;meltNum&quot;/&gt;
	&lt;/meltNum&gt;
	&lt;xsl:for-each select=&quot;key(&#39;a&#39;, meltNum)&quot;&gt;
	&lt;elemCode&gt;
		&lt;xsl:copy-of select=&quot;//elemCode&quot;/&gt;
	&lt;/elemCode&gt;
	&lt;/xsl:for-each&gt;   
&lt;/xsl:for-each&gt;

and then i got

 &lt;meltNum&gt;В301996&lt;/meltNum&gt;
        &lt;elemCode&gt;
          &lt;elemCode&gt;1&lt;/elemCode&gt;
          &lt;elemCode&gt;2&lt;/elemCode&gt;
          &lt;elemCode&gt;3&lt;/elemCode&gt;
          &lt;elemCode&gt;4&lt;/elemCode&gt;
          &lt;elemCode&gt;5&lt;/elemCode&gt;
        &lt;/elemCode&gt;
        &lt;meltNum&gt;99999&lt;/meltNum&gt;
        &lt;elemCode&gt;
          &lt;elemCode&gt;1&lt;/elemCode&gt;
          &lt;elemCode&gt;2&lt;/elemCode&gt;
          &lt;elemCode&gt;3&lt;/elemCode&gt;
          &lt;elemCode&gt;4&lt;/elemCode&gt;
          &lt;elemCode&gt;5&lt;/elemCode&gt;
        &lt;/elemCode&gt;

答案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

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;root&gt;
	&lt;meltChem&gt;
		&lt;meltNum&gt;301996&lt;/meltNum&gt;
		&lt;chem&gt;
			&lt;elemCode&gt;1&lt;/elemCode&gt;
			&lt;value&gt;0.052&lt;/value&gt;
		&lt;/chem&gt;
		&lt;chem&gt;
			&lt;elemCode&gt;2&lt;/elemCode&gt;
			&lt;value&gt;0.003&lt;/value&gt;
		&lt;/chem&gt;
		&lt;chem&gt;
			&lt;elemCode&gt;3&lt;/elemCode&gt;
			&lt;value&gt;0.0002&lt;/value&gt;
		&lt;/chem&gt;
	&lt;/meltChem&gt;
	&lt;meltChem&gt;
		&lt;meltNum&gt;99999&lt;/meltNum&gt;
		&lt;chem&gt;
			&lt;elemCode&gt;4&lt;/elemCode&gt;
			&lt;value&gt;0.052&lt;/value&gt;
		&lt;/chem&gt;
		&lt;chem&gt;
			&lt;elemCode&gt;5&lt;/elemCode&gt;
			&lt;value&gt;0.003&lt;/value&gt;
		&lt;/chem&gt;
	&lt;/meltChem&gt;
&lt;/root&gt;

XSLT #1

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
	&lt;xsl:output method=&quot;xml&quot; indent=&quot;yes&quot;/&gt;
	&lt;xsl:strip-space elements=&quot;*&quot;/&gt;

	&lt;!--Identity Transform pattern--&gt;
	&lt;xsl:template match=&quot;@*|node()&quot;&gt;
		&lt;xsl:copy&gt;
			&lt;xsl:apply-templates select=&quot;@*|node()&quot;/&gt;
		&lt;/xsl:copy&gt;
	&lt;/xsl:template&gt;

	&lt;xsl:template match=&quot;chem&quot;&gt;
		&lt;xsl:copy&gt;
            &lt;!--&lt;xsl:copy-of select=&quot;../meltNum&quot;/&gt;--&gt;
			&lt;xsl:copy-of select=&quot;preceding-sibling::meltNum&quot;/&gt;
			&lt;xsl:copy-of select=&quot;*&quot;/&gt;
		&lt;/xsl:copy&gt;
	&lt;/xsl:template&gt;

	&lt;!--remove meltNum element--&gt;
	&lt;xsl:template match=&quot;meltNum&quot;/&gt;
&lt;/xsl:stylesheet&gt;

XSLT #2

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
	&lt;xsl:output method=&quot;xml&quot; indent=&quot;yes&quot;/&gt;

	&lt;xsl:template match=&quot;/root&quot;&gt;
		&lt;xsl:copy&gt;
			&lt;xsl:for-each select=&quot;meltChem&quot;&gt;
				&lt;xsl:copy&gt;
				    &lt;xsl:variable name=&quot;meltNum&quot;&gt;
					    &lt;xsl:copy-of select=&quot;meltNum&quot;/&gt;
				    &lt;/xsl:variable&gt;
					&lt;xsl:for-each select=&quot;chem&quot;&gt;
						&lt;xsl:copy&gt;
							&lt;xsl:copy-of select=&quot;$meltNum&quot;/&gt;
							&lt;xsl:copy-of select=&quot;*&quot;/&gt;
						&lt;/xsl:copy&gt;
					&lt;/xsl:for-each&gt;
				&lt;/xsl:copy&gt;
			&lt;/xsl:for-each&gt;
		&lt;/xsl:copy&gt;
	&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

Output

&lt;?xml version=&#39;1.0&#39; ?&gt;
&lt;root&gt;
  &lt;meltChem&gt;
    &lt;chem&gt;
      &lt;meltNum&gt;301996&lt;/meltNum&gt;
      &lt;elemCode&gt;1&lt;/elemCode&gt;
      &lt;value&gt;0.052&lt;/value&gt;
    &lt;/chem&gt;
    &lt;chem&gt;
      &lt;meltNum&gt;301996&lt;/meltNum&gt;
      &lt;elemCode&gt;2&lt;/elemCode&gt;
      &lt;value&gt;0.003&lt;/value&gt;
    &lt;/chem&gt;
    &lt;chem&gt;
      &lt;meltNum&gt;301996&lt;/meltNum&gt;
      &lt;elemCode&gt;3&lt;/elemCode&gt;
      &lt;value&gt;0.0002&lt;/value&gt;
    &lt;/chem&gt;
  &lt;/meltChem&gt;
  &lt;meltChem&gt;
    &lt;chem&gt;
      &lt;meltNum&gt;99999&lt;/meltNum&gt;
      &lt;elemCode&gt;4&lt;/elemCode&gt;
      &lt;value&gt;0.052&lt;/value&gt;
    &lt;/chem&gt;
    &lt;chem&gt;
      &lt;meltNum&gt;99999&lt;/meltNum&gt;
      &lt;elemCode&gt;5&lt;/elemCode&gt;
      &lt;value&gt;0.003&lt;/value&gt;
    &lt;/chem&gt;
  &lt;/meltChem&gt;
&lt;/root&gt;

huangapple
  • 本文由 发表于 2023年2月20日 00:46:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75501736.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定