2013-06-03 3 views
-1

Мне нужно преобразовать ниже входной XML для вывода XML. Можете ли вы представить какие-либо идеи для этого.Проблема преобразования XSLT: от простого XML до многоуровневого XML

Мне нужно преобразовать ниже входной XML для вывода XML. Можете ли вы представить какие-либо идеи для этого.

Входной XML:

<GenericCollection ParamValue="ParamValue1" xmlns="http://www.example.org"> 
    <Generic> 
    <store>Store1</store> 
    <metricName>Metric1</metricName> 
    <metricValue>1</metricValue> 
    </Generic> 
    <Generic> 
    <store>Store1</store> 
    <metricName>Metric2</metricName> 
    <metricValue>1</metricValue> 
    </Generic> 
    <Generic> 
    <store>Store2</store> 
    <metricName>Metric1</metricName> 
    <metricValue>1</metricValue> 
    </Generic> 
    <Generic> 
    <store>Store2</store> 
    <metricName>Metric1</metricName> 
    <metricValue>2</metricValue> 
    </Generic> 
    <Generic> 
    <store>Store2</store> 
    <metricName>Metric2</metricName> 
    <metricValue>1</metricValue> 
    </Generic> 
    <Generic> 
    <store>Store3</store> 
    <metricName>Metric1</metricName> 
    <metricValue>1</metricValue> 
    </Generic> 
    <Generic> 
    <store>Store3</store> 
    <metricName>Metric1</metricName> 
    <metricValue>2</metricValue> 
    </Generic> 
</GenericCollection> 

выход:

<?xml version = '1.0' encoding = 'UTF-8'?> 
<ns4:EnterpriseDocument> 
    <ns4:DataSet> 
    <ns4:Dimension ref_name="bu_code" value="Store1"> 
     <ns4:Metric ref_name="Metric1"> 
     <ns4:Data value="1"/> 
     </ns4:Metric> 
     <ns4:Metric ref_name="Metric2"> 
     <ns4:Data value="1"/> 
     </ns4:Metric> 
    </ns4:Dimension> 
    <ns4:Dimension ref_name="bu_code" value="Store2"> 
     <ns4:Metric ref_name="Metric1"> 
     <ns4:Data value="1"/> 
     <ns4:Data value="2"/>    
     </ns4:Metric> 
     <ns4:Metric ref_name="Metric2"> 
     <ns4:Data value="1"/> 
     </ns4:Metric> 
    </ns4:Dimension> 
    <ns4:Dimension ref_name="bu_code" value="Store3"> 
     <ns4:Metric ref_name="Metric1"> 
     <ns4:Data value="1"/> 
     <ns4:Data value="2"/>    
     </ns4:Metric> 
    </ns4:Dimension>  
    </ns4:DataSet> 
</ns4:EnterpriseDocument> 
    Thanks, 
    Ramesh 
+0

Является ли это размещен XML правильно < здесь Пытались что-нибудь вам получить желаемое. output? –

+0

Я пробовал отправить «<» напрямую, а stackoverflow не принимал его. У меня не так много опыта в XSLT. Я использую Oracle BPEL XSLT и в настоящее время использую 3 цикла для каждого из них, чтобы добиться этого. Я хочу уменьшить этот цикл из-за проблем с производительностью – user2447671

+0

Поддерживает ли Oracle BPEL XSLT XSLT 2. 0? –

ответ

0

Если вы можете использовать XSLT 2.0, то вы, вероятно, следует с помощью XSL: для-каждой группе здесь , а не xsl: for-each, потому что вы пытаетесь сгруппировать элементы здесь.

Во-первых, вы группирование по Generic элементов по их стоимости магазин, так что вы написали бы это.

<xsl:for-each-group select="Generic" group-by="store"> 

Тогда в этом, вы бы вывести * Dimension * элемент для группы таким образом:

<Dimension ref_name="bu_code" value="{current-grouping-key()}"> 

Далее, вы хотите, чтобы в дальнейшем сгруппировать элементы в этой группе по их metricName значение

<xsl:for-each-group select="current-group()" group-by="metricName"> 

Обратите внимание на использование ток-группы() здесь. Вы выполняете только итерации по элементам в текущей группе «store», а не по всем общим элементам.

Наконец, чтобы вывести все свои данных элементов, вы могли бы сделать это

<xsl:for-each select="current-group()"> 

Попробуйте следующий XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xpath-default-namespace="http://www.example.org"> 

<xsl:output method="xml" indent="yes" /> 

<xsl:template match="/*"> 
    <EnterpriseDocument> 
    <DataSet> 
     <xsl:for-each-group select="Generic" group-by="store"> 
     <Dimension ref_name="bu_code" value="{current-grouping-key()}"> 
      <xsl:for-each-group select="current-group()" group-by="metricName"> 
       <Metric ref_name="{current-grouping-key()}"> 
        <xsl:for-each select="current-group()"> 
        <Data value="{metricValue}"/> 
        </xsl:for-each> 
       </Metric> 
      </xsl:for-each-group> 
     </Dimension> 
     </xsl:for-each-group> 
    </DataSet> 
    </EnterpriseDocument> 
</xsl:template> 

</xsl:stylesheet> 

При запуске на образец XML, следующий вывод (Примечание , в моем образце я не включаю пространства имен, просто для ясности)

<EnterpriseDocument> 
    <DataSet> 
     <Dimension ref_name="bu_code" value="Store1"> 
     <Metric ref_name="Metric1"> 
      <Data value="1"/> 
     </Metric> 
     <Metric ref_name="Metric2"> 
      <Data value="1"/> 
     </Metric> 
     </Dimension> 
     <Dimension ref_name="bu_code" value="Store2"> 
     <Metric ref_name="Metric1"> 
      <Data value="1"/> 
      <Data value="2"/> 
     </Metric> 
     <Metric ref_name="Metric2"> 
      <Data value="1"/> 
     </Metric> 
     </Dimension> 
     <Dimension ref_name="bu_code" value="Store3"> 
     <Metric ref_name="Metric1"> 
      <Data value="1"/> 
      <Data value="2"/> 
     </Metric> 
     </Dimension> 
    </DataSet> 
</EnterpriseDocument> 
0

И вот решение xslt-1.0. Что делает группировку, основанную на XSL: ключ (Muenchian Method

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:e="http://www.example.org" 
       xmlns:ns4="http://www.exampl.ns4.org"> 

    <xsl:strip-space elements="*" /> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:key name="kStore" match="e:Generic/e:store" use="."/> 
    <xsl:key name="kStoreMetric" match="e:Generic/e:metricName" use="concat(../e:store,'|', .)"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="e:GenericCollection"> 
     <ns4:EnterpriseDocument> 
     <xsl:for-each select="//e:Generic/e:store[ 
      generate-id() = generate-id(key('kStore', .) [1]) 
       ]" > 
      <ns4:DataSet> 
       <ns4:Dimension ref_name="bu_code" value="{.}"> 
        <xsl:variable name="s" select="." /> 
        <xsl:for-each select="//e:metricName[ 
          generate-id() = generate-id(key('kStoreMetric', concat($s,'|', .)) [1]) 
          ]" > 
         <ns4:Metric ref_name="{.}"> 
          <xsl:variable name="m" select="."/> 
          <xsl:for-each select="key('kStoreMetric', concat($s,'|', $m))" > 
           <ns4:Data value="{../e:metricValue}"/> 
          </xsl:for-each> 
         </ns4:Metric> 
        </xsl:for-each> 
       </ns4:Dimension> 
      </ns4:DataSet> 
      </xsl:for-each> 
     </ns4:EnterpriseDocument> 
    </xsl:template> 

</xsl:stylesheet> 

, который будет генерировать следующий вывод:

<ns4:EnterpriseDocument xmlns:ns4="http://www.exampl.ns4.org" xmlns:e="http://www.example.org"> 
    <ns4:DataSet> 
    <ns4:Dimension ref_name="bu_code" value="Store1"> 
     <ns4:Metric ref_name="Metric1"> 
     <ns4:Data value="1"/> 
     </ns4:Metric> 
     <ns4:Metric ref_name="Metric2"> 
     <ns4:Data value="1"/> 
     </ns4:Metric> 
    </ns4:Dimension> 
    </ns4:DataSet> 
    <ns4:DataSet> 
    <ns4:Dimension ref_name="bu_code" value="Store2"> 
     <ns4:Metric ref_name="Metric1"> 
     <ns4:Data value="1"/> 
     <ns4:Data value="2"/> 
     </ns4:Metric> 
     <ns4:Metric ref_name="Metric2"> 
     <ns4:Data value="1"/> 
     </ns4:Metric> 
    </ns4:Dimension> 
    </ns4:DataSet> 
    <ns4:DataSet> 
    <ns4:Dimension ref_name="bu_code" value="Store3"> 
     <ns4:Metric ref_name="Metric1"> 
     <ns4:Data value="1"/> 
     <ns4:Data value="2"/> 
     </ns4:Metric> 
    </ns4:Dimension> 
    </ns4:DataSet> 
</ns4:EnterpriseDocument> 
Смежные вопросы