1

我有几个自定义类型,它们有 2、3 或 4 个孩子。因此,无论我得到这些孩子,我都需要将它们组合成一个元素,该元素是输出 XML 中的父标记本身。由于缺乏 xslt 的经验,我尝试过但无法做到。任何人都可以帮助。

我的输入 XML。

<PERSON>
  <ID>194</ID>
  <NAME>IKHAJA</NAME>
  <DETAILS>
     <NUMBER>100</NUMBER>
     <Description />
     <NUMBER01 />
     <NUMBER02>Test</NUMBER02>
  </DETAILS>
  <STATUS>
     <NUMBER>ACTIVE</NUMBER>
     <Description>ACTIVE</Description>
     <NUMBER01 />
     <NUMBER02>ACTIVE</NUMBER02>
  </STATUS>
  <employer>
     <ID>123456</ID>
     <FNAME>EMPLOYER F NAME</FNAME>
     <LNAME>EMPLOYER L NAME</LNAME>
  </employer>
  <PERSON_OFF>
     <TYPE>
         <NUMBER>41</NUMBER>
         <Description>AMPLIFIERS</Description>
         <NUMBER01>77</NUMBER01>
         <NUMBER02 />
     </TYPE>
     <REPORT>
         <NUMBER />
         <Description />
         <NUMBER01 />
         <NUMBER02 />
     </REPORT>
     <SERIAL>111</SERIAL>
     <ADDITIONAL_DESC>TEST</ADDITIONAL_DESC>
     <KEY>5</KEY>
     <CREATED_BY>Test Guy</CREATED_BY>
     <CREATED_ON>2013-03-13T10:03:00</CREATED_ON>
     <PERSON_OFF_ONE>
         <BULK>
            <NUMBER>98078</NUMBER>
            <Description>BULK</Description>
            <NUMBER01 />
            <NUMBER02>8563</NUMBER02>
         </BULK>
         <CHECKED>Y</CHECKED>
     </PERSON_OFF_ONE>
  </PERSON_OFF>
</PERSON>

我的输出 XML 应该是这样的:

<PERSON>
   <ID>194</ID>
   <NAME>IKHAJA</NAME>
   <DETAILS>100;;;Test</DETAILS>
   <STATUS>ACTIVE;ACTIVE;;ACTIVE</STATUS>
   <employer>123456:EMPLOYER F NAME,EMPLOYER L NAME</employer>
   <PERSON_OFF>
       <TYPE>41;AMPLIFIERS;77;</TYPE>
       <REPORT>;;;</REPORT>
       <SERIAL>111</SERIAL>
       <ADDITIONAL_DESC>TEST</ADDITIONAL_DESC>
       <KEY>5</KEY>
       <CREATED_BY>Test Guy</CREATED_BY>
       <CREATED_ON>2013-03-13T10:03:00</CREATED_ON>
       <PERSON_OFF_ONE>
            <BULK>98078;BULK;;8563</BULK>
            <CHECKED>Y</CHECKED>
       </PERSON_OFF_ONE>
   </PERSON_OFF>
</PERSON>

如果您在此处观察详细信息,状态,批量等是我的自定义类型,它们具有子节点 NUMBER、Description、NUMBER01、NUMBRER02。我需要将它们与分隔符“;”结合起来 如果它们为空或为空,我将拥有“;;;” 在我的目标列中,如报告字段中所示。

此外,我还有一些雇主类型的字段,例如带有孩子 ID、FNAME 和 LNAME 的雇主,我应该将它们组合为 ID:FNAME、LNAME,如雇主字段所示。

我想如果我知道处理一种自定义类型,我可以轻松处理其他类型。

你能帮忙吗?我已经花了一整天的时间,我需要尽快做这件事。

4

2 回答 2

0

请试一试:

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

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

  <xsl:template match="DETAILS | STATUS | TYPE | REPORT | BULK">
    <xsl:copy>
      <xsl:apply-templates select="*" mode="delimit" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[position() > 1]" mode="delimit">
    <xsl:value-of select="concat(';', .)"/>
  </xsl:template>

  <xsl:template match="employer">
    <xsl:copy>
      <xsl:apply-templates select="*" mode="idlist" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ID" mode="idlist">
    <xsl:value-of select="concat(., ':')" />
  </xsl:template>

  <xsl:template match="*[not(self::ID)][position() > 1]" mode="idlist">
    <xsl:value-of select="concat(',', .)" />
  </xsl:template>
</xsl:stylesheet>

在您的示例输入上运行时,结果是:

<PERSON>
  <ID>194</ID>
  <NAME>IKHAJA</NAME>
  <DETAILS>100;;;Test</DETAILS>
  <STATUS>ACTIVE;ACTIVE;;ACTIVE</STATUS>
  <employer>123456:EMPLOYER F NAME,EMPLOYER L NAME</employer>
  <PERSON_OFF>
    <TYPE>41;AMPLIFIERS;77;</TYPE>
    <REPORT>;;;</REPORT>
    <SERIAL>111</SERIAL>
    <ADDITIONAL_DESC>TEST</ADDITIONAL_DESC>
    <KEY>5</KEY>
    <CREATED_BY>Test Guy</CREATED_BY>
    <CREATED_ON>2013-03-13T10:03:00</CREATED_ON>
    <PERSON_OFF_ONE>
      <BULK>98078;BULK;;8563</BULK>
      <CHECKED>Y</CHECKED>
    </PERSON_OFF_ONE>
  </PERSON_OFF>
</PERSON>
于 2013-04-04T16:29:31.910 回答
0

OP 对 JLRishe 的回答的评论

如果我列出了我所有的自定义类型,它就可以工作,但是在这里我有很多属于我的自定义类型的字段。除了列出“详细信息|状态|类型|报告|批量”之类的所有内容之外,有没有办法合并这些字段。

这很容易做到,因为所有这些可能有数百个父元素都有四个子元素之一

对 JLRishe 的解决方案进行的小幅调整适用于无限数量的父名称:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

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

  <xsl:template match="*[NUMBER|Description|NUMBER01|NUMBER02]">
            <xsl:copy>
              <xsl:apply-templates select="*" mode="delimit" />
            </xsl:copy>
  </xsl:template>

  <xsl:template match="*[position() > 1]" mode="delimit">
    <xsl:value-of select="concat(';', .)"/>
  </xsl:template>

  <xsl:template match="employer">
    <xsl:copy>
      <xsl:apply-templates select="*" mode="idlist" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ID" mode="idlist">
    <xsl:value-of select="concat(., ':')" />
  </xsl:template>

  <xsl:template match="*[not(self::ID)][position() > 1]" mode="idlist">
    <xsl:value-of select="concat(',', .)" />
  </xsl:template>
</xsl:stylesheet>

如您所见,此转换根本没有提及任何父名称,例如 DETAILS、STATUS、TYPE、REPORT、BULK、...等

当应用于提供的 XML 文档时,会产生所需的正确结果:

<PERSON>
   <ID>194</ID>
   <NAME>IKHAJA</NAME>
   <DETAILS>100;;;Test</DETAILS>
   <STATUS>ACTIVE;ACTIVE;;ACTIVE</STATUS>
   <employer>123456:EMPLOYER F NAME,EMPLOYER L NAME</employer>
   <PERSON_OFF>
      <TYPE>41;AMPLIFIERS;77;</TYPE>
      <REPORT>;;;</REPORT>
      <SERIAL>111</SERIAL>
      <ADDITIONAL_DESC>TEST</ADDITIONAL_DESC>
      <KEY>5</KEY>
      <CREATED_BY>Test Guy</CREATED_BY>
      <CREATED_ON>2013-03-13T10:03:00</CREATED_ON>
      <PERSON_OFF_ONE>
         <BULK>98078;BULK;;8563</BULK>
         <CHECKED>Y</CHECKED>
      </PERSON_OFF_ONE>
   </PERSON_OFF>
</PERSON>
于 2013-04-06T03:10:11.590 回答