如何从元素中创建新元素,该元素与XML中的子元素的属性值和第一个字母值有所不同?

时间:2017-08-31 09:05:03

标签: xml xslt

我正在研究使用Cooktop 2.5制作XSLT 1.0的学士学位,以便将XML文件转换为另一个。现在,我不得不改变这种形式的XML。我有这样的XML:

<PlantModel>
  <InstrumentLoop TagName="113">
    <Association Type="is a collection including" TagName="PI-113"/>
    <Association Type="is a collection including" TagName="PIT-113"/>
    <Association Type="is a collection including" TagName="TIT-113"/>
    <Association Type="is a collection including" TagName="TW-113"/>
    <Association Type="is a collection including" TagName="TI-113"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="107">
    <Association Type="is a collection including" TagName="LG-107"/>
    <Association Type="is a collection including" TagName="LIT-107"/>
    <Association Type="is a collection including" TagName="TW-107"/>
    <Association Type="is a collection including" TagName="TIT-107"/>
    <Association Type="is a collection including" TagName="PIT-107"/>
    <Association Type="is a collection including" TagName="LV-107"/>
    <Association Type="is a collection including" TagName="LIC-107"/>
    <Association Type="is a collection including" TagName="TI-107"/>
    <Association Type="is a collection including" TagName="PI-107"/>
  </InstrumentLoop>
</PlantModel>

我想把它变成这样:

<PlantModel>
  <InstrumentLoop TagName="P-113">
    <Association Type="is a collection including" TagName="PI-113"/>
    <Association Type="is a collection including" TagName="PIT-113"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="T-113">
    <Association Type="is a collection including" TagName="TIT-113"/>
    <Association Type="is a collection including" TagName="TW-113"/>
    <Association Type="is a collection including" TagName="TI-113"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="L-107">
    <Association Type="is a collection including" TagName="LG-107"/>
    <Association Type="is a collection including" TagName="LIT-107"/>
    <Association Type="is a collection including" TagName="LV-107"/>
    <Association Type="is a collection including" TagName="LIC-107"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="T-107">
    <Association Type="is a collection including" TagName="TI-107"/>
    <Association Type="is a collection including" TagName="TW-107"/>
    <Association Type="is a collection including" TagName="TIT-107"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="P-107">
    <Association Type="is a collection including" TagName="PIT-107"/>
    <Association Type="is a collection including" TagName="PI-107"/>
  </InstrumentLoop>
</PlantModel>

我从第一个答案中尝试过XSLT,然后像这样修改它:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:key name="key" match="/PlantModel/InstrumentLoop/Association" use="substring(@TagName,1,1)" />
<xsl:template match="/">
<Plantmodel>
<xsl:for-each select="/PlantModel/InstrumentLoop/@TagName">
<xsl:variable name="attrVal" select="." />
<xsl:for-each select="/PlantModel/InstrumentLoop/Association[generate-id() = generate-id(key('key',substring(@TagName,1,1))[1])]">
    <InstrumentLoop>
        <xsl:attribute name="TagName">
            <xsl:value-of select="concat(substring(@TagName,1,1),'-',$attrVal)" />
        </xsl:attribute>
        <xsl:for-each select="key('key',substring(@TagName,1,1))">
            <xsl:copy-of select="." />
        </xsl:for-each>
    </InstrumentLoop>
</xsl:for-each> 
</xsl:for-each>
</Plantmodel>
</xsl:template>
</xsl:stylesheet>

但是这会使关联元素输出像这样重复:

<PlantModel>
  <InstrumentLoop TagName="P-113">
     <Association Type="is a collection including" TagName="PI-113"/>
     <Association Type="is a collection including" TagName="PIT-113"/>
     <Association Type="is a collection including" TagName="PIT-107"/>
     <Association Type="is a collection including" TagName="PI-107"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="T-113">
     <Association Type="is a collection including" TagName="TIT-113"/>
     <Association Type="is a collection including" TagName="TW-113"/>
     <Association Type="is a collection including" TagName="TI-113"/>
     <Association Type="is a collection including" TagName="TI-107"/>
     <Association Type="is a collection including" TagName="TW-107"/>
     <Association Type="is a collection including" TagName="TIT-107"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="L-107">
     <Association Type="is a collection including" TagName="LG-107"/>
     <Association Type="is a collection including" TagName="LIT-107"/>
     <Association Type="is a collection including" TagName="LV-107"/>
     <Association Type="is a collection including" TagName="LIC-107"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="T-107">
     <Association Type="is a collection including" TagName="TIT-113"/>
     <Association Type="is a collection including" TagName="TW-113"/>
     <Association Type="is a collection including" TagName="TI-113"/>
     <Association Type="is a collection including" TagName="TI-107"/>
     <Association Type="is a collection including" TagName="TW-107"/>
     <Association Type="is a collection including" TagName="TIT-107"/>
  </InstrumentLoop>
  <InstrumentLoop TagName="P-107">
     <Association Type="is a collection including" TagName="PI-113"/>
     <Association Type="is a collection including" TagName="PIT-113"/>
     <Association Type="is a collection including" TagName="PIT-107"/>
     <Association Type="is a collection including" TagName="PI-107"/>
  </InstrumentLoop>
</PlantModel>

1 个答案:

答案 0 :(得分:0)

可以使用grouping XSLT来实现解决方案。以下是较新的示例输入XML的更新解决方案。可以通过创建key来实现输出,Association/@TagNamehyphen的第一个字符和|之后由分隔的<xsl:key name="key" match="Association" use="concat(substring(@TagName,1,1),'|',substring-after(@TagName,'-'))" /> 符号分隔的字符串的组合,希望不会出现输入XML。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="key" match="Association" use="concat(substring(@TagName,1,1),'|',substring-after(@TagName,'-'))" />
    <xsl:template match="/">
        <xsl:for-each select="//Association[generate-id() = generate-id(key('key',concat(substring(@TagName,1,1),'|',substring-after(@TagName,'-')))[1])]">
            <InstrumentLoop>
                <xsl:attribute name="TagName">
                    <xsl:value-of select="concat(substring(@TagName,1,1),'-',substring-after(@TagName,'-'))" />
                </xsl:attribute>
                <xsl:for-each select="key('key',concat(substring(@TagName,1,1),'|',substring-after(@TagName,'-')))">
                    <xsl:copy-of select="." />
                </xsl:for-each>
            </InstrumentLoop>
        </xsl:for-each> 
    </xsl:template>
</xsl:stylesheet>

XSLT 1.0

<InstrumentLoop>

上面的XSLT应用于修改后的样本输入XML即。多个<InstrumentLoop TagName="P-113"> <Association Type="is a collection including" TagName="PI-113" /> <Association Type="is a collection including" TagName="PIT-113" /> </InstrumentLoop> <InstrumentLoop TagName="T-113"> <Association Type="is a collection including" TagName="TIT-113" /> <Association Type="is a collection including" TagName="TW-113" /> <Association Type="is a collection including" TagName="TI-113" /> </InstrumentLoop> <InstrumentLoop TagName="L-107"> <Association Type="is a collection including" TagName="LG-107" /> <Association Type="is a collection including" TagName="LIT-107" /> <Association Type="is a collection including" TagName="LV-107" /> <Association Type="is a collection including" TagName="LIC-107" /> </InstrumentLoop> <InstrumentLoop TagName="T-107"> <Association Type="is a collection including" TagName="TW-107" /> <Association Type="is a collection including" TagName="TIT-107" /> <Association Type="is a collection including" TagName="TI-107" /> </InstrumentLoop> <InstrumentLoop TagName="P-107"> <Association Type="is a collection including" TagName="PIT-107" /> <Association Type="is a collection including" TagName="PI-107" /> </InstrumentLoop> 节点应在下面提供所需的输出。

<强>输出

{{1}}