/ / Extrahujte xml z opakujúcich sa prvkov založených na jedinečnom subreťaze v hodnote - xml, xslt, xslt-1.0, xslt-2.0

Extrahujte XML z opakujúcich sa prvkov založených na jedinečnom subreťaze v hodnote - xml, xslt, xslt-1.0, xslt-2.0

Snažím sa vytvoriť xml štruktúru, ktorá má opakovaný prvok založený na vstupnom xml. Vo vstupnom opakujúcom sa prvku MDMTagTagProperties má len 2 polia Key a Value, Na základe kľúčového poľa je potrebné vytvoriť prvok vo výstupnom XML a nastaviť obsah Value na to. Posledný 3 číselný znak Key sú pre jednu podmnožinu rovnaké. Nižšie uvádzame vstupný XML, xslt, ktorý sa snažím a požadovaný výstup.

vstup:

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

Akákoľvek pomoc by bola veľká priazeň.

odpovede:

1 pre odpoveď č. 1

Zvážte použitie kľúča na hľadanie ďalších hodnôt zo vstupného XML

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

Napríklad, vyhľadať MultiplicationFactor urobíte to takto:

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

Vyskúšajte tento 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>

Z hľadiska vašej očakávanej produkcie by ste mohli skutočne robiť toto všeobecnejšie. Vyskúšajte aj tento 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>

To by fungovalo iba vtedy, ak by všetky ns1:Key Hodnoty sú však vo forme "register.xxxxx.n.n.n".


1 pre odpoveď č. 2

Ako alternatívu je tu skupinový prístup 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>