XSLT:转换名称/值对并转换XML

时间:2017-09-30 12:25:39

标签: xslt-1.0 xslt-2.0

我需要将名称值对转换为XML。我能够生成XML,但元素名称应该分组,不应该重复。请看下面。 FieldValue元素在Detail节点中包含2个OrderItem值。如果带有OrderItem的FieldValue重复,则应将结果分组到一个OrderItem节点中。请帮忙。

源XML:

<SC>
	<Header>
		<Record>
			<FieldName>Schema</FieldName>
			<FieldValue>OrderHeader</FieldValue>
		</Record>
		<Record>
			<FieldName>Order</FieldName>
			<FieldValue>1234</FieldValue>
		</Record>
	</Header>
	<Detail>
		<Record>
			<FieldName>Schema</FieldName>
			<FieldValue>OrderItem</FieldValue>
		</Record>
		<Record>
			<FieldName>Item</FieldName>
			<FieldValue>1</FieldValue>
		</Record>
		<Record>
			<FieldName>Qty</FieldName>
			<FieldValue>10</FieldValue>
		</Record>
	</Detail>
	<Detail>
		<Record>
			<FieldName>Schema</FieldName>
			<FieldValue>OrderItem</FieldValue>
		</Record>
		<Record>
			<FieldName>Item</FieldName>
			<FieldValue>2</FieldValue>
		</Record>
		<Record>
			<FieldName>Qty</FieldName>
			<FieldValue>20</FieldValue>
		</Record>
	</Detail>
</SC>

目标XML:

<Order>
 <OrderItem>
   <Item>
      <Item>1</Item>
      <Qty>10</Qty>
   </Item>
   <Item>
      <Item>2</Item>
      <Qty>20</Qty>
   </Item>
 </OrderItem>
</Order>

XSLT:

<xsl:template match="@*|node()">
<Order>
    <xsl:for-each select="Detail">
        <Item>
            <xsl:apply-templates select="Record[position()>1]"/>
        </Item>
</xsl:for-each>
</Order>
</xsl:template>

<xsl:template match="Record">
    <xsl:element name="{FieldName}">
        <xsl:value-of select="FieldValue"/>
    </xsl:element>
</xsl:template>

2 个答案:

答案 0 :(得分:0)

似乎您正在尝试定义两个XSLT模板,只要一个就足够了。您希望在根上匹配,然后想要迭代每个SC/Detail

然后,你想获取FieldName节点的兄弟的FieldValue,它是'Item'(对于项目值)和'Qty'(对于数量值),但只有'Record'下列出的那些。

注意:您已在转换后的输出中指定了双重嵌套<Item>,此解决方案反映了该要求。

此XSLT应该按照您的要求执行:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
  <xsl:for-each select="SC/Detail">
<Order>
  <OrderItem>
    <Item>
    <Item>
      <xsl:value-of select="Record[FieldName[text()='Item']]/FieldValue" />
    </Item>
    <Qty>
      <xsl:value-of select="Record[FieldName[text()='Qty']]/FieldValue" />
    </Qty>
    </Item>
  </OrderItem>
</Order>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

分组可以按如下方式进行:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output indent="yes"/>

    <xsl:template match="SC">
        <Order>
            <xsl:for-each-group select="Detail" group-by="Record[1]/FieldValue">
                <xsl:element name="{current-grouping-key()}">
                    <xsl:apply-templates select="current-group()"/>
                </xsl:element>
            </xsl:for-each-group>
        </Order>
    </xsl:template>

    <xsl:template match="Detail">
        <Item>
            <xsl:apply-templates select="Record[position() gt 1]"/>
        </Item>
    </xsl:template>

    <xsl:template match="Record">
        <xsl:element name="{FieldName}">
            <xsl:value-of select="FieldValue"/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>