英文:
XSLT: XML to JSON - If key/s repeated in data, Merge the Key/s data into one Key concatenate with ";"- "KEY1": "Rate1: - 2000; Rate2: - 3000"
问题
XSLT:合并“LineTransaction”关键列,如果有多个!!
请参考以下XML和JSON,并分享正确的XSLT代码
Source XML Data:
  <wd:Report_Entry>
    <wd:InvoiceRefID>INVOICE-9999</wd:InvoiceRefID>
    <wd:InvoiceNumber>999-1234</wd:InvoiceNumber>
    <wd:InvoiceLine>
    <wd:InvoiceLineRefID>INVOICE_LINE-9999-1</wd:InvoiceLineRefID>
    <wd:LineTransaction wd:Descriptor="Tax Rate1: - 2000">
    <wd:ID wd:type="WID">83888d0f7bb710017f5517e62ca00001</wd:ID>
    </wd:LineTransaction>
    <wd:LineTransaction wd:Descriptor="Vertex Tax Rate2: - 3000">
    <wd:ID wd:type="WID">83888d0f7bb710017f55174bfa7a0002</wd:ID>
    </wd:LineTransaction>
    </wd:InvoiceLine>
    </wd:Report_Entry>
请参考以下XSLT代码,
XSLT Code
<xsl:stylesheet
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:wd="urn:com.workday/InvoiceAndInvoiceLine" version="3.0">
	<xsl:output method="text"/>
	<xsl:variable name="linefeed" select="' '"/>
	<xsl:variable name="delimiter" select="'|'"/>
	<xsl:template match="/">
		<xsl:text>[&#xa;</xsl:text>
		<xsl:apply-templates select="wd:Report_Data/wd:Report_Entry"/>
        <xsl:text>&#xa;]</xsl:text>
	</xsl:template>
	<xsl:template match="wd:Report_Entry">
		<xsl:text> &#xA0;{&#xa; </xsl:text>
		<xsl:apply-templates select="* except wd:InvoiceLine"/>
		<xsl:text>,&#xa;"invoiceLine": [ &#xa; </xsl:text>
		<xsl:apply-templates select="wd:InvoiceLine/*[not(self::wd:LineTransaction)]"/>
        <xsl:text>&#xa; &#xA0; ] &#xa; &#xA0; } </xsl:text>
		<xsl:if test="position() != last()">
			<xsl:text>,&#xa;</xsl:text>
		</xsl:if>
	</xsl:template>
	<xsl:template match="wd:LineTransaction">
        <xsl:if test="position() != 1">
            <xsl:text>;&#xa;</xsl:text>
        </xsl:if>
        <xsl:value-of select="@wd:Descriptor"/>
	</xsl:template>
	<xsl:template match="wd:*">
		<xsl:text>&#xA0;</xsl:text>
		<xsl:choose> 
			<xsl:when test="@wd:Descriptor"><xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',@wd:Descriptor,'&quot;')"/></xsl:when>
			<xsl:otherwise><xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',.,'&quot;')"/></xsl:otherwise>
		</xsl:choose>
		<xsl:if test="position() != last()">
			<xsl:text>,&#xa;</xsl:text>
		</xsl:if>
	</xsl:template>
	<xsl:template match="wd:InvoiceLine">
		<xsl:text> &#xA0; { &#xa;</xsl:text>
		<xsl:apply-templates select="* except wd:LineTransaction"/>
        <xsl:text>,&#xa; </xsl:text>
		<xsl:apply-templates select="wd:LineTransaction"/>
		<xsl:text>&#xa; &#xA0; }</xsl:text>
		<xsl:if test="position() != last()">
			<xsl:text>,&#xa; </xsl:text>
		</xsl:if>		
	</xsl:template>
	<xsl:template match="wd:InvoiceLine/*">
		<xsl:choose> 
			<xsl:when test="@wd:Descriptor">
			<xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',@wd:Descriptor,'&quot;')"/>
			</xsl:when>
			<xsl:otherwise>
			<xsl:value-of select="concat('&
英文:
XSLT : Merge "LineTransaction" Key column if more than one !!
Please refer below XML and JSON and share the correct XSLT Code
Source XML Data :
  <wd:Report_Entry>
    <wd:InvoiceRefID>INVOICE-9999</wd:InvoiceRefID>
    <wd:InvoiceNumber>999-1234</wd:InvoiceNumber>
    <wd:InvoiceLine>
    <wd:InvoiceLineRefID>INVOICE_LINE-9999-1</wd:InvoiceLineRefID>
    <wd:LineTransaction wd:Descriptor="Tax Rate1: - 2000">
    <wd:ID wd:type="WID">83888d0f7bb710017f5517e62ca00001</wd:ID>
    </wd:LineTransaction>
    <wd:LineTransaction wd:Descriptor="Vertex Tax Rate2: - 3000">
    <wd:ID wd:type="WID">83888d0f7bb710017f55174bfa7a0002</wd:ID>
    </wd:LineTransaction>
    </wd:InvoiceLine>
    </wd:Report_Entry>
Please refer below XSLT Code,
XSLT Code
<xsl:stylesheet
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:wd="urn:com.workday/InvoiceAndInvoiceLine" version="3.0">
	<xsl:output method="text"/>
	<xsl:variable name="linefeed" select="' '"/>
	<xsl:variable name="delimiter" select="'|'"/>
	<xsl:template match="/">
		<xsl:text>[&#xa;</xsl:text>
		<xsl:apply-templates select="wd:Report_Data/wd:Report_Entry"/>
        <xsl:text>&#xa;]</xsl:text>
	</xsl:template>
	<xsl:template match="wd:Report_Entry">
		<xsl:text> &#xA0;{&#xa; </xsl:text>
		<xsl:apply-templates select="* except wd:InvoiceLine"/>
		<xsl:text>,&#xa;"invoiceLine": [ &#xa; </xsl:text>
		<xsl:apply-templates select="wd:InvoiceLine"/>
		<xsl:text>&#xa; &#xA0; ] &#xa; &#xA0; } </xsl:text>
		<xsl:if test="position() != last()">
			<xsl:text>,&#xa;</xsl:text>
		</xsl:if>
	</xsl:template>
	<xsl:template match="wd:*">
		<xsl:text>&#xA0;</xsl:text>
		<xsl:choose> 
			<xsl:when test="@wd:Descriptor"><xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',@wd:Descriptor,'&quot;')"/></xsl:when>
			<xsl:otherwise><xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',.,'&quot;')"/></xsl:otherwise>
		</xsl:choose>
		<xsl:if test="position() != last()">
			<xsl:text>,&#xa;</xsl:text>
		</xsl:if>
	</xsl:template>
	<xsl:template match="wd:InvoiceLine">
		<xsl:text> &#xA0; { &#xa;</xsl:text>
		<xsl:apply-templates select="*"/>
		<xsl:text>&#xa; &#xA0; }</xsl:text>
		<xsl:if test="position() != last()">
			<xsl:text>,&#xa; </xsl:text>
		</xsl:if>		
	</xsl:template>
	<xsl:template match="wd:InvoiceLine/*">
		<xsl:choose> 
			<xsl:when test="@wd:Descriptor">
			<xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',@wd:Descriptor,'&quot;')"/>
			</xsl:when>
			<xsl:otherwise>
			<xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',.,'&quot;')"/>
			</xsl:otherwise>
		</xsl:choose>
		<xsl:if test="position() != last()">
			<xsl:text>,&#xa; </xsl:text>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>
Here is JSON Output:
[
 {
 "InvoiceRefID":"INVOICE-9999",
 "InvoiceNumber":"999-1234",
 "invoiceLine": [ 
	{ 
	  "InvoiceLineRefID":"INVOICE_LINE-9999-1",
	  "LineTransaction": "Tax Rate1: - 2000",
      "LineTransaction": "Tax Rate2: - 3000"
	}
  ]
  }
]
Here is Expected JSON Output: above XSLT code not produced right outout
[
	 {
	 "InvoiceRefID":"INVOICE-9999",
	 "InvoiceNumber":"999-1234",
	 "invoiceLine": [ 
		{ 
		  "InvoiceLineRefID":"INVOICE_LINE-9999-1",
		  "LineTransaction": "Tax Rate1: - 2000; Tax Rate2: - 3000"
		}
	  ]
	  }
	]
Please verify above and share right solution.
答案1
得分: 1
您的XSLT声明了version="3.0"。如果您的处理器支持XSLT 3.0,我建议您执行以下操作:
XSLT 3.0
<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2005/xpath-functions"
xmlns:wd="urn:com.workday/InvoiceAndInvoiceLine">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
    <!-- 转换输入为JSON的XML -->
    <xsl:variable name="xml">
        <xsl:apply-templates/>
    </xsl:variable>
    <!-- 输出 -->
    <xsl:value-of select="xml-to-json($xml)"/>
</xsl:template>
<xsl:template match="wd:Report_Data">
    <array>
        <xsl:apply-templates/>
    </array>
</xsl:template>
<xsl:template match="wd:Report_Entry">
    <map>
        <xsl:apply-templates/>
    </map>
</xsl:template>
<xsl:template match="wd:InvoiceRefID | wd:InvoiceNumber">
    <string key="{local-name()}">
        <xsl:value-of select="."/>
    </string>
</xsl:template>
<xsl:template match="wd:InvoiceLine">
    <array key="invoiceLine">
        <map>
            <string key="InvoiceLineRefID">
                <xsl:value-of select="wd:InvoiceLineRefID"/>
            </string>
            <string key="LineTransaction">
                <xsl:value-of select="wd:LineTransaction/@wd:Descriptor" separator="; "/>
            </string>
        </map>
    </array>
</xsl:template>
</xsl:stylesheet>
对于一个格式良好的XML输入:
XML
<wd:Report_Data xmlns:wd="urn:com.workday/InvoiceAndInvoiceLine">
    <wd:Report_Entry>
        <wd:InvoiceRefID>INVOICE-9999</wd:InvoiceRefID>
        <wd:InvoiceNumber>999-1234</wd:InvoiceNumber>
        <wd:InvoiceLine>
            <wd:InvoiceLineRefID>INVOICE_LINE-9999-1</wd:InvoiceLineRefID>
            <wd:LineTransaction wd:Descriptor="Tax Rate1: - 2000">
                <wd:ID wd:type="WID">83888d0f7bb710017f5517e62ca00001</wd:ID>
            </wd:LineTransaction>
            <wd:LineTransaction wd:Descriptor="Vertex Tax Rate2: - 3000">
                <wd:ID wd:type="WID">83888d0f7bb710017f55174bfa7a0002</wd:ID>
            </wd:LineTransaction>
        </wd:InvoiceLine>
    </wd:Report_Entry>
</wd:Report_Data>
将生成:
Result
[{"InvoiceRefID":"INVOICE-9999","InvoiceNumber":"999-1234","invoiceLine":[{"InvoiceLineRefID":"INVOICE_LINE-9999-1","LineTransaction":"Tax Rate1: - 2000; Vertex Tax Rate2: - 3000"}]}]
英文:
Your XSLT declares version="3.0". If your processor supports XSLT 3.0 then I would suggest you do:
XSLT 3.0
<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2005/xpath-functions"
xmlns:wd="urn:com.workday/InvoiceAndInvoiceLine">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
	<!-- CONVERT INPUT TO XML FOR JSON -->
	<xsl:variable name="xml">
		<xsl:apply-templates/>
	</xsl:variable>
	<!-- OUTPUT -->
	<xsl:value-of select="xml-to-json($xml)"/>
</xsl:template>
<xsl:template match="wd:Report_Data">
	<array>
		<xsl:apply-templates/>
	</array>
</xsl:template>
<xsl:template match="wd:Report_Entry">
	<map>
		<xsl:apply-templates/>
	</map>
</xsl:template>
<xsl:template match="wd:InvoiceRefID | wd:InvoiceNumber">
	<string key="{local-name()}">
		<xsl:value-of select="."/>
	</string>
</xsl:template>
<xsl:template match="wd:InvoiceLine">
	<array key="invoiceLine">
		<map>
			<string key="InvoiceLineRefID">
				<xsl:value-of select="wd:InvoiceLineRefID"/>
			</string>
			<string key="LineTransaction">
				<xsl:value-of select="wd:LineTransaction/@wd:Descriptor" separator="; "/>
			</string>
		</map>
	</array>
</xsl:template>
	
</xsl:stylesheet>
With a well-formed (!) XML input:
XML
<wd:Report_Data xmlns:wd="urn:com.workday/InvoiceAndInvoiceLine">
	<wd:Report_Entry>
		<wd:InvoiceRefID>INVOICE-9999</wd:InvoiceRefID>
		<wd:InvoiceNumber>999-1234</wd:InvoiceNumber>
		<wd:InvoiceLine>
			<wd:InvoiceLineRefID>INVOICE_LINE-9999-1</wd:InvoiceLineRefID>
			<wd:LineTransaction wd:Descriptor="Tax Rate1: - 2000">
				<wd:ID wd:type="WID">83888d0f7bb710017f5517e62ca00001</wd:ID>
			</wd:LineTransaction>
			<wd:LineTransaction wd:Descriptor="Vertex Tax Rate2: - 3000">
				<wd:ID wd:type="WID">83888d0f7bb710017f55174bfa7a0002</wd:ID>
			</wd:LineTransaction>
		</wd:InvoiceLine>
	</wd:Report_Entry>
</wd:Report_Data>
this will produce:
Result
[{"InvoiceRefID":"INVOICE-9999","InvoiceNumber":"999-1234","invoiceLine":[{"InvoiceLineRefID":"INVOICE_LINE-9999-1","LineTransaction":"Tax Rate1: - 2000; Vertex Tax Rate2: - 3000"}]}]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论