使用XSL将原始输入XML转换为结构化XML

时间:2016-02-09 18:00:06

标签: xml xslt grouping

我尝试使用XSL和“for-each” 我需要根据CATEGORY和TYPE对值进行分组。

任何帮助?

输入RAW xml:

<?xml version = '1.0' encoding = 'UTF-8'?>
<ROWSET>
<ROW>
<ID>12345</ID>
<TYPE>TYP1</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>1</VALUE>
<LABEL>ISO1</LABEL>
</ROW>
<ROW>
<ID>12345</ID>
<TYPE>TYP1</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>2</VALUE>
<LABEL>ISO2</LABEL>
</ROW>
<ROW>
<ID>12345</ID>
<TYPE>TYP1</TYPE>
<SUBTYPE>SUBTYP2</SUBTYP>
<CATEGORY>A1</CATEGORY>
<VALUE>3</VALUE>
<LABEL>ISO3</LABEL>
</ROW>
<ROW>
<ID>67890</ID>
<TYPE>TYP1</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>1</VALUE>
<LABEL>ISO1</LABEL>
</ROW>
<ROW>
<ID>67890</ID>
<TYPE>TYP1</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>1</VALUE>
<LABEL>ISO1</LABEL>
</ROW>
<ROW>
<ID>67890</ID>
<TYPE>TYP1</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>2</VALUE>
<LABEL>ISO2</LABEL>
</ROW>
<ROW>
<ID>67890</ID>
<TYPE>TYP2</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>3</VALUE>
<LABEL>ISO3</LABEL>
</ROW>
<ROW>
<ID>67890</ID>
<TYPE>TYP2</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>2</VALUE>
<LABEL>ISO2</LABEL>
</ROW>
<ROW>
<ID>67890</ID>
<TYPE>TYP2</TYPE>
<CATEGORY>A1</CATEGORY>
<VALUE>3</VALUE>
<LABEL>ISO1</LABEL>
</ROW>
</ROWSET>

预期结果 我需要根据Category和TYPE对值进行分组(见下文)

<?xml version = '1.0' encoding = 'UTF-8'?>
<ROWSET>
<ROW>
<ID>12345</ID>
    <TYPE>TYP1</TYPE>
<CATEGORY>A1</CATEGORY>
    <GRP1>
    <VALUE>1</VALUE>
    <LABEL>ISO1</LABEL>
    <VALUE>2</VALUE>
    <LABEL>ISO2</LABEL>
    <VALUE>3</VALUE>
    <LABEL>ISO3</LABEL>
    </GRP1>         
</ROW>
<ROW>
<ID>67890</ID>
  <TYP>
    <TYPE>TYP1</TYPE>
    <TYPE>TYP2</TYPE>
  </TYP>
<CATEGORY>A1</CATEGORY>
    <GRP1>
    <VALUE>1</VALUE>
    <LABEL>ISO1</LABEL>
    <VALUE>2</VALUE>
    <LABEL>ISO2</LABEL>
    <VALUE>3</VALUE>
    <LABEL>ISO3</LABEL>
    </GRP1>         

使用XSL:需要进行一些更正。 (感谢@Parfait代码)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

<xsl:key name="categkey" match="ROW" use="CATEGORY" />

<xsl:template match="ROWSET">
<xsl:copy>
  <xsl:for-each select="ROW[generate-id()= generate-id(key('categkey', CATEGORY)[1])]">
    <xsl:copy>
      <xsl:copy-of select="ID"/>
      <xsl:copy-of select="TYPE"/>
      <xsl:copy-of select="CATEGORY"/>
      <GRP1>
        <xsl:for-each select="key('categkey', CATEGORY)">            
            <xsl:copy-of select="VALUE"/>
            <xsl:copy-of select="LABEL"/>            
        </xsl:for-each>
      </GRP1>
    </xsl:copy>
  </xsl:for-each>
    </xsl:copy>
 </xsl:template>
</xsl:transform>

谢谢! Carthyc

1 个答案:

答案 0 :(得分:1)

对于XSLT 1.0中的分组,请考虑Muenchian Method根据密钥对文档编制索引,并可以使用该密钥运行各种操作:

ID

<强>更新

借用@Tim C的previous answer(首次编辑你的帖子的XSLT大师),对于<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output version="1.0" encoding="UTF-8" indent="yes" /> <xsl:strip-space elements="*"/> <xsl:key name="idkey" match="ROW" use="ID" /> <xsl:key name="typekey" match="ROW" use="concat(ID, TYPE)"/> <xsl:key name="categkey" match="ROW" use="concat(ID, CATEGORY)" /> <xsl:key name="valuekey" match="ROW" use="concat(ID, VALUE)" /> <xsl:key name="labelkey" match="ROW" use="concat(ID, LABEL)" /> <xsl:template match="ROWSET"> <xsl:copy> <xsl:for-each select="ROW[generate-id()= generate-id(key('idkey', ID)[1])]"> <xsl:copy> <xsl:copy-of select="ID"/> <TYP> <xsl:for-each select="key('idkey', ID)[generate-id()= generate-id(key('typekey', concat(ID, TYPE))[1])]"> <xsl:copy-of select="TYPE"/> </xsl:for-each> </TYP> <xsl:copy-of select="CATEGORY"/> <GRP1> <xsl:for-each select="key('idkey', ID)[generate-id()= generate-id(key('valuekey', concat(ID, VALUE))[1])]"> <xsl:copy-of select="VALUE"/> <xsl:copy-of select="LABEL"/> </xsl:for-each> </GRP1> </xsl:copy> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:transform> 及其兄弟姐妹等多个键,请考虑以下内容:

read -r userline
printf "%s\n" "${userline}"> textfile