英文:
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:
<?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>
<!-- Your `substring-before` will not work on strings without the dash. Try tokenize instead -->
<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>
Using this source 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>
will give this result:
<?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>
答案2
得分: 0
另一个简单的解决方案是在开罗放一头大象:
group-by="substring-before(concat(ExternalBatchNo, '-'), '-')"
英文:
Another simple solution is to place an elephant in Cairo:
group-by="substring-before(concat(ExternalBatchNo, '-'), '-')"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论