2017-09-30 52 views
0

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

源XML:

<SC> 
 
\t <Header> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Schema</FieldName> 
 
\t \t \t <FieldValue>OrderHeader</FieldValue> 
 
\t \t </Record> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Order</FieldName> 
 
\t \t \t <FieldValue>1234</FieldValue> 
 
\t \t </Record> 
 
\t </Header> 
 
\t <Detail> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Schema</FieldName> 
 
\t \t \t <FieldValue>OrderItem</FieldValue> 
 
\t \t </Record> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Item</FieldName> 
 
\t \t \t <FieldValue>1</FieldValue> 
 
\t \t </Record> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Qty</FieldName> 
 
\t \t \t <FieldValue>10</FieldValue> 
 
\t \t </Record> 
 
\t </Detail> 
 
\t <Detail> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Schema</FieldName> 
 
\t \t \t <FieldValue>OrderItem</FieldValue> 
 
\t \t </Record> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Item</FieldName> 
 
\t \t \t <FieldValue>2</FieldValue> 
 
\t \t </Record> 
 
\t \t <Record> 
 
\t \t \t <FieldName>Qty</FieldName> 
 
\t \t \t <FieldValue>20</FieldValue> 
 
\t \t </Record> 
 
\t </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> 

回答

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> 
0

看起来您正试图定义两个XSLT模板,当一个应该足够时。你想匹配根,然后你想遍历每个SC/Detail

然后,您想要获取'Item'(对于项目值)和'Qty'(对于数量值)的FieldName节点的兄弟的FieldValue,但只包含'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> 
+0

您好,感谢您的投入。 OrderItem元素应该从名称值对动态创建。元素/节点不是静态的。它是动态的。 – user8696326

+0

该要求在您的问题中提供的代码中不明确。如果您可以更新您的问题(即更新您期望的目标XML的外观),那么我可以为您更新我的答案。 – jhenderson2099