Xslt XML输出,元素值作为标记名,下一个后续元素值作为所创建标记的值

Xslt XML输出,元素值作为标记名,下一个后续元素值作为所创建标记的值,xslt,ibm-integration-bus,extended-sql,Xslt,Ibm Integration Bus,Extended Sql,我需要形成一个输出xml,其中需要将字段值作为标记,然后将随后的下一个字段值作为所创建标记的值 <PrimaryKey> <PK1FeildName>CONNO</PK1FeildName> <PK1Value>001</PK1Value> <PK2FeildName>INNO</PK2FeildName> <PK2Value>123</PK2Value>

我需要形成一个输出xml,其中需要将字段值作为标记,然后将随后的下一个字段值作为所创建标记的值

<PrimaryKey>
    <PK1FeildName>CONNO</PK1FeildName>
    <PK1Value>001</PK1Value>
    <PK2FeildName>INNO</PK2FeildName>
    <PK2Value>123</PK2Value>
    <PK3FeildName>CONNO</PK3FeildName>
    <PK3Value>011</PK3Value>
</PrimaryKey>
预期产出:

<PrimaryKey>
  <CONNO>001</CONNO>
  <INNO>123</INNO>
  <CONNO>011</CONNO>
</PrimaryKey>

如果认为元素总是成对出现,其中第一个元素的值是标签名,第二个元素是值,则这样工作:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="PrimaryKey">
      <xsl:element name="PrimaryKey">
          <xsl:apply-templates/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="*">
    <xsl:if test="count(preceding-sibling::*) mod 2 = 0">
        <xsl:element name="{.}">
            <xsl:value-of select="following-sibling::*[1]"/>
        </xsl:element>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
您可以在这里尝试:

编辑以回答评论

XML示例:

<Document>
    <PrimaryKey>
        <PK1FeildName>CONNO</PK1FeildName>
        <PK1Value>001</PK1Value>
        <PK2FeildName>INNO</PK2FeildName>
        <PK2Value>123</PK2Value>
        <PK3FeildName>CONNO</PK3FeildName>
        <PK3Value>011</PK3Value>
    </PrimaryKey>
    <PrimaryKey>
        <PK1FeildName>CONNO2</PK1FeildName>
        <PK1Value>0012</PK1Value>
        <PK2FeildName>INNO2</PK2FeildName>
        <PK2Value>1232</PK2Value>
        <PK3FeildName>CONNO2</PK3FeildName>
        <PK3Value>0112</PK3Value>
    </PrimaryKey>
</Document>
修改的XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
      <xsl:element name="PrimaryKey">
          <xsl:apply-templates/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="PrimaryKey/*">
    <xsl:if test="count(preceding-sibling::*) mod 2 = 0">
        <xsl:element name="{.}">
            <xsl:value-of select="following-sibling::*[1]"/>
        </xsl:element>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

为了完整起见,这里有一个使用ESQL而不是XSLT的解决方案:

CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
    -- Get a reference to the first instance of 'PK1FeildName'
    DECLARE refPK REFERENCE TO InputRoot.XMLNSC.PrimaryKey.PK1FeildName[1];
    WHILE LASTMOVE(refPK) DO
        -- remember the field name 
        DECLARE keyName CHARACTER FIELDVALUE(refPK);
        MOVE refPK NEXTSIBLING;

        -- create the next field in the output
        CREATE LASTCHILD OF OutputRoot.XMLNSC.Document.PrimaryKey TYPE NameValue NAME keyName VALUE FIELDVALUE(refPK);
        MOVE refPK NEXTSIBLING;
    END WHILE;

    RETURN TRUE;
END;

无论您使用XSL还是ESQL,我都建议您根据XSD验证传入的XML,因为映射代码取决于以特定顺序查看特定标记。您可以添加代码来检查标记名,但XSD验证是一个更简单的解决方案。

我注意到您在本文中添加了“esql”标记。您使用的是IBM集成总线吗?是的,我使用的是IBM集成总线,但我一直试图通过读取字段名来实现逻辑,并在输出树结构中捕获它,但我无法根据需要获取标记及其各自的值。。。到目前为止,我已经在两种不同的树结构中实现了字段名和值的逻辑,但稍后我将再次在子字符串级别对其进行比较,我不确定如何进一步注意字段的拼写是thusly而不是feild。这是否是您的问题的一个因素,由您来决定。谢谢Sebastian,我只是想问您,如果primarykey标记多次出现,它是如何工作的,我是否需要提及带有主根标记名称的模板?我只是想了解一下模板的工作原理,因为我是Xslt的初学者。CONNO 001 INNO 123 CONNO 011查看我修改后的答案,以将包含多个XML的XML考虑在内。非常感谢Sebastian的帮助,我学习的一个问题如下兄弟:*[1]充当循环中读取的特定字段的值?在match=PrimaryKey/*模板中,if语句检查元素的位置是否为偶数,即一对中的第一个元素。以下同级::*[1]语句选择下一个元素的值。因此,第一个元素成为节点的名称,第二个元素成为值。如果您的问题得到了回答,请通过接受答案来结束它。谢谢Kimbert,这非常有帮助。