我正在尝试创建具有基于输入xml的重复元素的xml结构。在输入重复元素MDMTagTagProperties
中只有2个字段Key
和Value
。基于Key字段,我们需要在输出xml中创建一个元素,并将Value
字段的内容设置为该元素。 Key
字段的最后3个数字字符对于一个子集是相同的。下面是输入XML,我正在尝试的xslt和Desired Output。
输入:
<?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>
任何帮助都会很有帮助。
答案 0 :(得分: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”时才有效。
答案 1 :(得分: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>