按两个条件分组在一个元素中

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

Group-by two conditions in one element

问题

以下是您要翻译的部分:

"I am trying to group-by two conditions in one element, which practically means that machine and parts with same ID (before '-' should be grouped.

Input:

<Document>
	<DocumentLine>
		<ExternalBatchNo>KEC36770</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36770-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-3</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
</Document>

Expected result:

<Document>
	<DocumentLine>
		<ExternalBatchNo>KEC36770</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36770-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
</Document>

<Document>
	<DocumentLine>
		<ExternalBatchNo>KEC36771</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-3</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
</Document>

This is what I tried, but this results in an empty machine ID and so only groups on parts.

<xsl:for-each-group select="Message/Documents/Document/DocumentLine" group-by="substring-before(ExternalBatchNo,'-')">

So I am thinking about using some template where he should pick the ExternalBatchNo when value doesn't contain an '-'. But, how?"

英文:

I am trying to group-by two conditions in one element, which practically means that machine and parts with same ID (before '-' should be grouped.

Input:

<Document>
	<DocumentLine>
		<ExternalBatchNo>KEC36770</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36770-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-3</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
</Document>

Expected result:

<Document>
	<DocumentLine>
		<ExternalBatchNo>KEC36770</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36770-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
</Document>

<Document>
	<DocumentLine>
		<ExternalBatchNo>KEC36771</ExternalBatchNo>
		<Attribute01>machine</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-2</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
	<DocumentLine>
		<ExternalBatchNo>KEC36771-3</ExternalBatchNo>
		<Attribute01>part</Attribute01>
	</DocumentLine>
</Document>

This is what I tried, but this results in an empty machine ID and so only groups on parts.

<xsl:for-each-group select="Message/Documents/Document/DocumentLine" group-by="substring-before(ExternalBatchNo,'-')">

So I am thinking about using some template where he should pick the ExternalBatchNo when value doesn't contain an '-'. But, how?

答案1

得分: 0

如果您可以使用XSLT版本2.0,您可以使用以下方式:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  
  <xsl:output indent="yes"/>
  
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="Documents">
    <xsl:copy>
      <!-- 您的 `substring-before` 在没有短横线的字符串上不起作用。请尝试使用 tokenize 替代 -->
      <xsl:for-each-group select="Document/DocumentLine" group-by="tokenize(ExternalBatchNo,'-')[1]">
        <Document>
          <xsl:copy-of select="current-group()"/>
        </Document>
      </xsl:for-each-group>    
    </xsl:copy>
  </xsl:template>  

</xsl:stylesheet>

使用此源XML:

<?xml version="1.0" encoding="UTF-8"?>
<Message>
  <Documents>
    <Document>
      <DocumentLine>
        <ExternalBatchNo>KEC36770</ExternalBatchNo>
        <Attribute01>machine</Attribute01>
      </DocumentLine>
      <DocumentLine>
        <ExternalBatchNo>KEC36770-2</ExternalBatchNo>
        <Attribute01>part</Attribute01>
      </DocumentLine>
      <DocumentLine>
        <ExternalBatchNo>KEC36771</ExternalBatchNo>
        <Attribute01>machine</Attribute01>
      </DocumentLine>
      <DocumentLine>
        <ExternalBatchNo>KEC36771-2</ExternalBatchNo>
        <Attribute01>part</Attribute01>
      </DocumentLine>
      <DocumentLine>
        <ExternalBatchNo>KEC36771-3</ExternalBatchNo>
        <Attribute01>part</Attribute01>
      </DocumentLine>
    </Document>    
  </Documents>
</Message>

将产生以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<Documents>
   <Document>
      <DocumentLine>
         <ExternalBatchNo>KEC36770</ExternalBatchNo>
         <Attribute01>machine</Attribute01>
      </DocumentLine>
      <DocumentLine>
         <ExternalBatchNo>KEC36770-2</ExternalBatchNo>
         <Attribute01>part</Attribute01>
      </DocumentLine>
   </Document>
   <Document>
      <DocumentLine>
         <ExternalBatchNo>KEC36771</ExternalBatchNo>
         <Attribute01>machine</Attribute01>
      </DocumentLine>
      <DocumentLine>
         <ExternalBatchNo>KEC36771-2</ExternalBatchNo>
         <Attribute01>part</Attribute01>
      </DocumentLine>
      <DocumentLine>
         <ExternalBatchNo>KEC36771-3</ExternalBatchNo>
         <Attribute01>part</Attribute01>
      </DocumentLine>
   </Document>
</Documents>
英文:

If you can use xslt version 2.0, you could use something like this:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;xsl:stylesheet 
  xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
  version=&quot;2.0&quot;&gt;
  
  &lt;xsl:output indent=&quot;yes&quot;/&gt;
  
  &lt;xsl:strip-space elements=&quot;*&quot;/&gt;
  
  &lt;xsl:template match=&quot;Documents&quot;&gt;
    &lt;xsl:copy&gt;
      &lt;!-- Your `substring-before` will not work on strings without the dash. Try tokenize instead --&gt;
      &lt;xsl:for-each-group select=&quot;Document/DocumentLine&quot; group-by=&quot;tokenize(ExternalBatchNo,&#39;-&#39;)[1]&quot;&gt;
        &lt;Document&gt;
          &lt;xsl:copy-of select=&quot;current-group()&quot;/&gt;
        &lt;/Document&gt;
      &lt;/xsl:for-each-group&gt;    
    &lt;/xsl:copy&gt;
  &lt;/xsl:template&gt;  

&lt;/xsl:stylesheet&gt;

Using this source xml:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;Message&gt;
  &lt;Documents&gt;
    &lt;Document&gt;
      &lt;DocumentLine&gt;
        &lt;ExternalBatchNo&gt;KEC36770&lt;/ExternalBatchNo&gt;
        &lt;Attribute01&gt;machine&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
      &lt;DocumentLine&gt;
        &lt;ExternalBatchNo&gt;KEC36770-2&lt;/ExternalBatchNo&gt;
        &lt;Attribute01&gt;part&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
      &lt;DocumentLine&gt;
        &lt;ExternalBatchNo&gt;KEC36771&lt;/ExternalBatchNo&gt;
        &lt;Attribute01&gt;machine&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
      &lt;DocumentLine&gt;
        &lt;ExternalBatchNo&gt;KEC36771-2&lt;/ExternalBatchNo&gt;
        &lt;Attribute01&gt;part&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
      &lt;DocumentLine&gt;
        &lt;ExternalBatchNo&gt;KEC36771-3&lt;/ExternalBatchNo&gt;
        &lt;Attribute01&gt;part&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
    &lt;/Document&gt;    
  &lt;/Documents&gt;
&lt;/Message&gt;

will give this result:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;Documents&gt;
   &lt;Document&gt;
      &lt;DocumentLine&gt;
         &lt;ExternalBatchNo&gt;KEC36770&lt;/ExternalBatchNo&gt;
         &lt;Attribute01&gt;machine&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
      &lt;DocumentLine&gt;
         &lt;ExternalBatchNo&gt;KEC36770-2&lt;/ExternalBatchNo&gt;
         &lt;Attribute01&gt;part&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
   &lt;/Document&gt;
   &lt;Document&gt;
      &lt;DocumentLine&gt;
         &lt;ExternalBatchNo&gt;KEC36771&lt;/ExternalBatchNo&gt;
         &lt;Attribute01&gt;machine&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
      &lt;DocumentLine&gt;
         &lt;ExternalBatchNo&gt;KEC36771-2&lt;/ExternalBatchNo&gt;
         &lt;Attribute01&gt;part&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
      &lt;DocumentLine&gt;
         &lt;ExternalBatchNo&gt;KEC36771-3&lt;/ExternalBatchNo&gt;
         &lt;Attribute01&gt;part&lt;/Attribute01&gt;
      &lt;/DocumentLine&gt;
   &lt;/Document&gt;
&lt;/Documents&gt;

答案2

得分: 0

另一个简单的解决方案是在开罗放一头大象

group-by=&quot;substring-before(concat(ExternalBatchNo, &#39;-&#39;), &#39;-&#39;)&quot;
英文:

Another simple solution is to place an elephant in Cairo:

group-by=&quot;substring-before(concat(ExternalBatchNo, &#39;-&#39;), &#39;-&#39;)&quot;

huangapple
  • 本文由 发表于 2023年7月20日 16:34:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76728060.html
匿名

发表评论

匿名网友

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

确定