平面字符串转换的多个元素

时间:2017-06-06 19:57:29

标签: xml xslt xpath xslt-1.0 xslt-2.0

我希望从源xml转换多个元素,并将它们组合在逗号分隔文本中的单个目标字符串元素中。

条件 源输入是布尔类型,仅当值为true时才应包含在目标列表中

E.g。 XML

<Root-Element>
<EnggTypes>
<Engg1>true</Engg1>
<Engg2>true</Engg2>
<Engg3>false</Engg3>
<Engg4>false</Engg4>
<Engg5>true</Engg5>
</EnggTypes>
</Root-Element>

预期转变

<Root-Element>
<RoleTypes>Role1,Role2,Role5</RoleTypes>
</Root-Element>

希望在XSL 1.0或2.0中实现相同的目标

我开始过度思考并尝试在目标端使用变量来查看我是否可以选择/何时使用先前的值构造字符串并连接但似乎不会起作用,因为变量值一旦设置就无法更改!

<xsl:variable name="roleVar">
<xsl:if test="Engg1/text()='true'">Role1</if>
<xsl:if test="Engg2/text()='true'">concat(roleVar,",",Role2)</if>
<xsl:if test="Engg3/text()='true'">concat(roleVar,",",Role3)</if>
<xsl:if test="Engg4/text()='true'">concat(roleVar,",",Role4)</if>
<xsl:if test="Engg5/text()='true'">concat(roleVar,",",Role5)</if>
</xsl:variable>

赞赏任何投入。

提前致谢

2 个答案:

答案 0 :(得分:2)

您可以选择这些元素并在一个表达式中构造值:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

    <xsl:template match="EnggTypes">
        <xsl:copy>
            <xsl:value-of select="*[. = 'true']/concat('Role', replace(local-name(), '[^0-9]+', ''))" separator=","/>
        </xsl:copy>
    </xsl:template>

</xsl:transform>

http://xsltransform.net/bEzjRJR/1给出了

<Root-Element>
<EnggTypes>Role1,Role2,Role5</EnggTypes>
</Root-Element>

答案 1 :(得分:2)

XSLT 1.0解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="EnggTypes">
    <xsl:copy>
      <RoleTypes>
        <xsl:apply-templates select="*[starts-with(local-name(), 'Engg')][text() = 'true']"/>
      </RoleTypes>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[starts-with(local-name(), 'Engg')][text() = 'true']">
    <xsl:value-of select="concat('Role', substring-after(local-name(), 'Engg'))"/>

    <xsl:if test="position() != last()">
      <xsl:text>,</xsl:text>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>