2016-04-05 49 views
1

中的唯一子字符串從重複元素中提取xml我想創建具有基於輸入xml的重複元素的xml結構。在輸入重複元素MDMTagTagProperties只有2個字段KeyValue。基於Key字段,我們需要在輸出xml中創建一個元素,並將Value字段的內容設置爲該字段。 Key字段的最後3個數字字符對於一個子集是相同的。以下是我正在嘗試的輸入XML,xslt和期望輸出。基於值

輸入:

<?xml version="1.0" encoding="UTF-8"?> 
<ns1:Properties xmlns:ns1="http://www.test.org/cmm/xsd/mdmtag_01"> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.MeteringDirection.2.8.1</ns1:Key> 
     <ns1:Value>TLV</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.MultiplicationFactor.1.8.2</ns1:Key> 
     <ns1:Value>2.0</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.MeasureUnit.2.8.1</ns1:Key> 
     <ns1:Value>KWH</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.RegisterType.1.8.2</ns1:Key> 
     <ns1:Value>N</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.MeteringDirection.1.8.2</ns1:Key> 
     <ns1:Value>LVR</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.MultiplicationFactor.2.8.1</ns1:Key> 
     <ns1:Value>5.0</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.NrOfDigits.1.8.2</ns1:Key> 
     <ns1:Value>5</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.MeasureUnit.1.8.2</ns1:Key> 
     <ns1:Value>KWH</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.RegisterType.2.8.1</ns1:Key> 
     <ns1:Value>P</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.NrOfDigits.2.8.1</ns1:Key> 
     <ns1:Value>4</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.Id.2.8.1</ns1:Key> 
     <ns1:Value>2.8.1</ns1:Value> 
    </ns1:MDMTagTagProperties> 
    <ns1:MDMTagTagProperties> 
     <ns1:Key>register.Id.1.8.2</ns1:Key> 
     <ns1:Value>1.8.2</ns1:Value> 
    </ns1:MDMTagTagProperties> 
</ns1:Properties> 

XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="http://www.test.org/cmm/xsd/mdmtag_01" xmlns:ns5="http://www.test.org/cmm/xsd/outputmdmtag_01" exclude-result-prefixes="ns1" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="/ns1:Properties"> 
    <ns5:Output> 
     <xsl:for-each select="ns1:MDMTagTagProperties[contains(ns1:Key,'register.Id')]"> 
      <ns5:Register> 
       <ns5:RegisterId> 
        <xsl:value-of select="current()/ns1:Value[contains(ns1:Key,'register.Id')]" /> 
       </ns5:RegisterId> 

       <ns5:RegisterType> 
       <xsl:value-of select="current()/ns1:Value[contains(ns1:Key,'register.RegisterType')]" /> 
       </ns5:RegisterType> 
       <ns5:RegisterMultiplicationFactor> 
        <xsl:value-of select="current()/ns1:Value[contains(ns1:Key,'register.RegisterMultiplicationFactor')]" /> 
       </ns5:RegisterMultiplicationFactor> 
        <ns5:RegisterMeteringDirection> 
        <xsl:value-of select="current()/ns1:Value[contains(ns1:Key,'register.RegisterMeteringDirection')]" /> 
       </ns5:RegisterMeteringDirection> 
       <ns5:RegisterMeasureUnit> 
        <xsl:value-of select="current()/ns1:Value[contains(ns1:Key,'register.RegisterMeasureUnit')]" /> 
       </ns5:RegisterMeasureUnit> 
       <ns5:RegisterNrOfDigits> 
        <xsl:value-of select="current()/ns1:Value[contains(ns1:Key,'register.RegisterNrOfDigits')]" /> 
       </ns5:RegisterNrOfDigits> 
      </ns5:Register> 
     </xsl:for-each> 
    </ns5:Output> 
</xsl:template> 
</xsl:stylesheet> 

CurrentOutput:

<?xml version="1.0" encoding="UTF-8"?> 
<ns5:Output xmlns:ns5="http://www.test.org/cmm/xsd/outputmdmtag_01"> 
    <ns5:Register> 
     <ns5:RegisterId /> 
     <ns5:RegisterType /> 
     <ns5:RegisterMultiplicationFactor /> 
     <ns5:RegisterMeteringDirection /> 
     <ns5:RegisterMeasureUnit /> 
     <ns5:RegisterNrOfDigits /> 
    </ns5:Register> 
    <ns5:Register> 
     <ns5:RegisterId /> 
     <ns5:RegisterType /> 
     <ns5:RegisterMultiplicationFactor /> 
     <ns5:RegisterMeteringDirection /> 
     <ns5:RegisterMeasureUnit /> 
     <ns5:RegisterNrOfDigits /> 
    </ns5:Register> 
</ns5:Output> 

ExpectedOutput:

<?xml version="1.0" encoding="UTF-8"?> 
<ns5:Output xmlns:ns5="http://www.test.org/cmm/xsd/outputmdmtag_01"> 
    <ns5:Register> 
     <ns5:RegisterId>1.8.2</ns5:RegisterId> 
     <ns5:RegisterType>N</ns5:RegisterType> 
     <ns5:RegisterMultiplicationFactor>2.0</ns5:RegisterMultiplicationFactor> 
     <ns5:RegisterMeteringDirection>LVR</ns5:RegisterMeteringDirection> 
     <ns5:RegisterMeasureUnit>KHW</ns5:RegisterMeasureUnit> 
     <ns5:RegisterNrOfDigits>5</ns5:RegisterNrOfDigits> 
    </ns5:Register> 
    <ns5:Register> 
     <ns5:RegisterId>2.8.1</ns5:RegisterId> 
     <ns5:RegisterType>P</ns5:RegisterType> 
     <ns5:RegisterMultiplicationFactor>5.0</ns5:RegisterMultiplicationFactor> 
     <ns5:RegisterMeteringDirection>TLV</ns5:RegisterMeteringDirection> 
     <ns5:RegisterMeasureUnit>KWH</ns5:RegisterMeasureUnit> 
     <ns5:RegisterNrOfDigits>4</ns5:RegisterNrOfDigits> 
    </ns5:Register> 
</ns5:Output> 

任何幫助將是一個很大的忙。

回答

1

考慮使用一鍵輸入XML

<xsl:key name="tags" match="ns1:MDMTagTagProperties" use="ns1:Key" /> 

它們,例如,以查找MultiplicationFactor你會做這個查找其他值:

<xsl:value-of select="key('tags', concat('register.MultiplicationFactor.', ns1:Value))/ns1:Value" /> 

試試這個XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="http://www.test.org/cmm/xsd/mdmtag_01" xmlns:ns5="http://www.test.org/cmm/xsd/outputmdmtag_01" exclude-result-prefixes="ns1" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:key name="tags" match="ns1:MDMTagTagProperties" use="ns1:Key" /> 

    <xsl:template match="/ns1:Properties"> 
    <ns5:Output> 
     <xsl:for-each select="ns1:MDMTagTagProperties[starts-with(ns1:Key,'register.Id')]"> 
      <ns5:Register> 
       <ns5:RegisterId> 
        <xsl:value-of select="ns1:Value" /> 
       </ns5:RegisterId> 
       <ns5:RegisterType> 
        <xsl:value-of select="key('tags', concat('register.RegisterType.', ns1:Value))/ns1:Value" /> 
       </ns5:RegisterType> 
       <ns5:RegisterMultiplicationFactor> 
        <xsl:value-of select="key('tags', concat('register.MultiplicationFactor.', ns1:Value))/ns1:Value" /> 
       </ns5:RegisterMultiplicationFactor> 
       <ns5:RegisterMeteringDirection> 
        <xsl:value-of select="key('tags', concat('register.MeteringDirection.', ns1:Value))/ns1:Value" /> 
       </ns5:RegisterMeteringDirection> 
       <ns5:RegisterMeasureUnit> 
        <xsl:value-of select="key('tags', concat('register.MeasureUnit.', ns1:Value))/ns1:Value" /> 
       </ns5:RegisterMeasureUnit> 
       <ns5:RegisterNrOfDigits> 
        <xsl:value-of select="key('tags', concat('register.NrOfDigits.', ns1:Value))/ns1:Value" /> 
       </ns5:RegisterNrOfDigits> 
      </ns5:Register> 
     </xsl:for-each> 
    </ns5:Output> 
</xsl:template> 
</xsl:stylesheet> 

從看你的預期產出,你可能實際上這更通用。試試這個XSLT太:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="http://www.test.org/cmm/xsd/mdmtag_01" xmlns:ns5="http://www.test.org/cmm/xsd/outputmdmtag_01" exclude-result-prefixes="ns1" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:key name="tags" match="ns1:MDMTagTagProperties" use="substring-after(substring-after(ns1:Key, '.'), '.')" /> 

    <xsl:template match="/ns1:Properties"> 
    <ns5:Output> 
     <xsl:for-each select="ns1:MDMTagTagProperties[contains(ns1:Key,'register.Id')]"> 
      <ns5:Register> 
       <xsl:for-each select="key('tags', ns1:Value)"> 
        <xsl:element name="ns5:Register{substring-before(substring-after(ns1:Key, '.'), '.')}"> 
         <xsl:value-of select="ns1:Value" /> 
        </xsl:element> 
       </xsl:for-each> 
      </ns5:Register> 
     </xsl:for-each> 
    </ns5:Output> 
</xsl:template> 
</xsl:stylesheet> 

如果所有ns1:Key值的形式是「register.xxxxx.n.n.n」的,雖然這隻會工作。

+0

完善。你做了我的一天。謝謝蒂姆! –

1

作爲替代方案,在這裏是一個XSLT 2.0分組的方法:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" 
    xpath-default-namespace="http://www.test.org/cmm/xsd/mdmtag_01" 
    xmlns:ns5="http://www.test.org/cmm/xsd/outputmdmtag_01" version="2.0"> 

    <xsl:param name="result-order" as="xs:string*" 
     select="'register.Id', 'register.RegisterType', 'register.MultiplicationFactor', 'register.MeteringDirection', 'register.MeasureUnit'"/> 

    <xsl:output indent="yes"/> 

    <xsl:template match="Properties"> 
     <ns5:Output> 
      <xsl:for-each-group select="MDMTagTagProperties" 
       group-by="substring(Key, string-length(Key) - 4)"> 
       <ns5:Register> 
        <xsl:apply-templates select="current-group()"> 
         <xsl:sort 
          select="index-of($result-order, substring(Key, 1, string-length(Key) - 6))" 
         /> 
        </xsl:apply-templates> 
       </ns5:Register> 
      </xsl:for-each-group> 
     </ns5:Output> 
    </xsl:template> 

    <xsl:template match="MDMTagTagProperties"> 
     <xsl:element name="ns5:{replace(Key, '\.[0-9]', '')}"> 
      <xsl:value-of select="Value"/> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet>