首页 > 解决方案 > 匹配不工作并希望动态输出标签

问题描述

我有一个来自 Cognos 系统的源 xml,我希望使用 xsl 转换为输出 xml:

<dataset  xmlns="http://developer.cognos.com/schemas/xmldata/1/"  xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
    <item name="REFWO" type="xs:string" length="18"/>
    <item name="STARTDATEENTERED" type="xs:string" length="16002"/>
    <item name="REGULARHRS" type="xs:string" length="102"/>
    <item name="SOMEDESC" type="xs:string" length="16002"/>
    <item name="LABORCODE" type="xs:string" length="26"/>
    <item name="GENAPPRSERVRECEIPT" type="xs:string" length="4"/>
    <item name="GLCREDITACCT" type="xs:string" length="52"/>
    <item name="OUTSIDE" type="xs:string" length="4"/>
    <item name="SITEID" type="xs:string" length="12"/>
    <item name="TOTREC" type="xs:int" precision="1"/>
</metadata>
<data>
    <row>

        <value>12345678</value>
        <value>2020-12-22</value>
        <value>2.00</value>
        <value>MECHANIC</value>
        <value>ABCD01</value>
        <value>0</value>
        <value>11111.11.1111.1111.111.11</value>
        <value>0</value>
        <value>CDEFG</value>
        <value>5</value>
    </row>
    <row>
        <value>12345678</value>
        <value>2020-12-22</value>
        <value>2.00</value>
        <value>MECHANIC</value>
        <value>ABCD02</value>
        <value>1</value>
        <value>11111.11.1111.1111.111.11</value>
        <value>1</value>
        <value>CDEFG</value>
        <value>5</value>
    </row>
</data>

这是我试图开始的xsl ..最初的问题是它从不执行匹配..它是我的命名空间吗?(第二个问题是我正在尝试动态构建输出标签,但我不确定该方法。)

    <xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"  exclude-result-prefixes="xs">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
    <xsl:apply-templates select="xs:dataset"/>
</xsl:template>

<xsl:template match="xs:dataset">
        <xsl:text>
        </xsl:text>
    <xsl:for-each select="xs:dataset/xs:data/xs:row">
                <xsl:text>
                </xsl:text>
        <!--<xsl:value-of select="max:OBJECTNAME" />
        <xsl:value-of select="max:NAME" />-->
        <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
        <xsl:value-of select="//dataset/metadata/item[1]/@name" />
        <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
        <xsl:value-of
                    select="concat(xs:value[1],'.',xs:NAME)"/>
        <xsl:text disable-output-escaping="yes">&lt;/</xsl:text>

        <xsl:value-of select="//dataset/metadata/item[1]/@name" />
        <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
    </xsl:for-each>

</xsl:template>

</xsl:stylesheet>

我不知道我动态构建标签的方法是否正确。我被一个相当旧版本的 xls 处理器困住了。

例如,元数据中的第一行是这样的:

<metadata>
    <item name="REFWO" type="xs:string" length="18"/>

表示每个第一行值标签的输出标签看起来像这样

<LABTRANS><REFWO>12345678</REFWO>

如果第一个元数据行是这样的:

<metadata>
    <item name="STARTDATEENTERED" type="xs:string" length="16002"/>

然后我需要的输出标签看起来像这样(因此动态构建输出标签):

<LABTRANS><STARTDATEENTERED>12345678</STARTDATEENTERED>

预期的最终输出如下...请注意输出中的标签来自该位置的数据

/dataset/metadata/item

每个标签的实际数据来自该位置的每个提供的输入值

/dataset/data/row/value

这是迄今为止的xsl:

<?xml version="1.0" encoding="UTF-8"?>
<PublishTSTLABTRANS xmlns="http://www.ibm.com/maximo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" creationDateTime="2021-05-20T20:31:26-04:00" transLanguage="EN" baseLanguage="EN" messageID="155701621557087518337" maximoVersion="7 6 20190514-1348 V7611-365" event="0">
  <TSTLABTRANSSet>
    <LABTRANS>
      <GENAPPRSERVRECEIPT>1</GENAPPRSERVRECEIPT>
      <GLCREDITACCT>11111.11.1111.1111.111.11</GLCREDITACCT>
      <LABORCODE>ABCD01</LABORCODE>
      <MEMO>MECHANIC</MEMO>
      <ORGID>OFMC</ORGID>
      <OUTSIDE>0</OUTSIDE>
      <OWNERSYSID />
      <REFWO>12345678</REFWO>
      <REGULARHRS>2</REGULARHRS>
      <SENDERSYSID>CO</SENDERSYSID>
      <SITEID>CDEFG</SITEID>
      <STARTDATEENTERED>2020-12-22T00:00:00-05:00</STARTDATEENTERED>
    </LABTRANS>
    <LABTRANS>
      <GENAPPRSERVRECEIPT>1</GENAPPRSERVRECEIPT>
      <GLCREDITACCT>11111.11.1111.1111.111.11</GLCREDITACCT>
      <LABORCODE>ABCD02</LABORCODE>
      <MEMO>MECHANIC</MEMO>
      <ORGID>OFMC</ORGID>
      <OUTSIDE>1</OUTSIDE>
      <OWNERSYSID />
      <REFWO>12345678</REFWO>
      <REGULARHRS>2</REGULARHRS>
      <SENDERSYSID>CO</SENDERSYSID>
      <SITEID>CDEFG</SITEID>
      <STARTDATEENTERED>2020-12-22T00:00:00-05:00</STARTDATEENTERED>
    </LABTRANS>
  </TSTLABTRANSSet>
</PublishTSTLABTRANS>

任何提示/评论/说明/ptr 表示赞赏。尤其是我的脑死“为什么不匹配”

标签: xmlxslt-1.0

解决方案


我建议您按照以下方式尝试:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cgn="http://developer.cognos.com/schemas/xmldata/1/"
xmlns="http://www.ibm.com/maximo" 
exclude-result-prefixes="cgn">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/cgn:dataset">
    <xsl:variable name="field-labels" select="cgn:metadata/cgn:item" />
    <PublishTSTLABTRANS>
        <TSTLABTRANSSet>
            <xsl:for-each select="cgn:data/cgn:row">
                <LABTRANS>
                    <xsl:for-each select="cgn:value">
                        <xsl:variable name="i" select="position()" />
                        <xsl:element name="{$field-labels[$i]/@name}">
                            <xsl:value-of select="."/>
                        </xsl:element>
                    </xsl:for-each>
                </LABTRANS>
            </xsl:for-each>
        </TSTLABTRANSSet>
    </PublishTSTLABTRANS>
</xsl:template>

</xsl:stylesheet>

笔记:

  1. 使用前缀声明命名空间,cgn以及在寻址源 XML 中的元素时使用此前缀;

  2. 声明默认命名空间以将输出的所有元素放置在该命名空间中;

  3. 使用xsl:element指令创建名称在运行时动态确定的元素;

  4. 使用属性值模板来计算元素的名称。

我不确定PublishTSTLABTRANS元素属性中显示的数据应该来自哪里。


推荐阅读