使用给定的XML实现嵌套/层次结构

时间:2014-09-16 16:19:37

标签: xml xslt-1.0

这是我的一些xml数据,一个相当扁平的结构,itemMapCode = 1 / itemValue = * values,标记我们拥有的数据类型。 M =主要部分,C =类别,W =要嵌套在类别中的工作代码,H代表标题。

<?xml version="1.0" encoding="UTF-8"?>
<EstimateDisplayRequest>
<facXML>
    <faRecord>
        <recordCode>33</recordCode>
        <item>
            <itemMapCode>1</itemMapCode>
            <itemValue>M</itemValue>
        </item>
        <item>
            <itemMapCode>10</itemMapCode>
            <itemValue>CL1</itemValue>
        </item>
        <item>
            <itemMapCode>11</itemMapCode>
            <itemValue>Rodick Client</itemValue>
        </item>
        <item>
            <itemMapCode>12</itemMapCode>
            <itemValue>P1</itemValue>
        </item>
        <item>
            <itemMapCode>13</itemMapCode>
            <itemValue>Rodick Product</itemValue>
        </item>
        <item>
            <itemMapCode>14</itemMapCode>
            <itemValue>AD0242</itemValue>
        </item>
        <item>
            <itemMapCode>15</itemMapCode>
            <itemValue>copy1</itemValue>
        </item>            
    </faRecord>
  <faRecord>
     <recordCode>33</recordCode>
     <item>
        <itemMapCode>1</itemMapCode>
        <itemValue>C</itemValue>
     </item>
     <item>
        <itemMapCode>80</itemMapCode>
        <itemValue>0</itemValue>
     </item>
     <item>
        <itemMapCode>81</itemMapCode>
        <itemValue>INTERNAL CREATIVE</itemValue>
     </item>        
  </faRecord>
  <faRecord>
     <recordCode>33</recordCode>
     <item>
        <itemMapCode>1</itemMapCode>
        <itemValue>W</itemValue>
     </item>
     <item>
        <itemMapCode>41</itemMapCode>
        <itemValue>0</itemValue>
     </item>
     <item>
        <itemMapCode>42</itemMapCode>
        <itemValue>TI</itemValue>
     </item>
     <item>
        <itemMapCode>43</itemMapCode>
        <itemValue>Time Work Code</itemValue>
     </item>         
  </faRecord>
  <faRecord>
     <recordCode>33</recordCode>
     <item>
        <itemMapCode>1</itemMapCode>
        <itemValue>W</itemValue>
     </item>
     <item>
        <itemMapCode>41</itemMapCode>
        <itemValue>0</itemValue>
     </item>
     <item>
        <itemMapCode>42</itemMapCode>
        <itemValue>AD</itemValue>
     </item>
     <item>
        <itemMapCode>43</itemMapCode>
        <itemValue>ART DIRECTION</itemValue>
     </item>         
  </faRecord>

    <faRecord>
        <recordCode>33</recordCode>
        <item>
            <itemMapCode>1</itemMapCode>
            <itemValue>H</itemValue>
        </item>
        <item>
            <itemMapCode>90</itemMapCode>
            <itemValue>Text &amp; Talk is a double-blind peer-reviewed journal published by Mouton de Gruyter. It provides an international and interdisciplinary forum for publication of research in "language, discourse, and communication studies".&lt;nl&gt;&lt;nl&gt;The journal was first</itemValue>
        </item>
    </faRecord>
    <faRecord>
        <recordCode>33</recordCode>
        <item>
            <itemMapCode>1</itemMapCode>
            <itemValue>H</itemValue>
        </item>
        <item>
            <itemMapCode>90</itemMapCode>
            <itemValue> published under the name TEXT in 1981.</itemValue>
        </item>
    </faRecord>        
</facXML>
</EstimateDisplayRequest>

我有的XSL(在这个论坛的帮助下派生!)可以正常使用M部分和嵌套的C / W部分,但是我遇到了H / header部分的问题。我尝试使用generateKey方法,就像我用于C和W一样,但如果我用M / H尝试它,它就不起作用。

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

<xsl:key name="kWork" match="faRecord[item[itemMapCode = 1]/itemValue = 'W']" use="
generate-id(preceding-sibling::faRecord[item[itemMapCode = 1]/itemValue = 'C'][1])
" />

<xsl:template match="EstimateDisplayRequest">
<MCSResponse>
  <EstimateDisplayResponse>
    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'M']" />
    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'C']" />

    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'H']" />
    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'F']" />
  </EstimateDisplayResponse>
</MCSResponse>
</xsl:template>

<xsl:template match="faRecord[item[itemMapCode = 1]/itemValue = 'M']">
<EstimateDetail>
  <xsl:apply-templates select="item" />
</EstimateDetail>
</xsl:template>

<xsl:template match="faRecord[item[itemMapCode = 1]/itemValue = 'C']">
<CategoryDetail>
  <xsl:apply-templates select="item" />      
  <xsl:apply-templates select="key('kWork', generate-id())" />
</CategoryDetail>
</xsl:template>

<xsl:template match="faRecord[item[itemMapCode = 1]/itemValue = 'W']">
<WorkcodeDetail>
  <xsl:apply-templates select="item" />      
</WorkcodeDetail>
</xsl:template>

<xsl:template match="faRecord[item[itemMapCode = 1]/itemValue = 'H']">
<EstimateHeader>
  <xsl:apply-templates select="item" />
</EstimateHeader>
</xsl:template>

<!-- this catches <recordCode> and unknown elements -->
<xsl:template match="faRecord/recordCode" />
<xsl:template match="faRecord/item[itemMapCode=1]" />

<xsl:template match="faRecord/item[itemMapCode!=1]">
<xsl:variable name="elemName">
  <xsl:choose>
    <xsl:when test="itemMapCode = 2">SortKey</xsl:when>
    <xsl:when test="itemMapCode = 3">SideBySideSequential</xsl:when>

    <xsl:when test="itemMapCode = 10">ClientCode</xsl:when>
    <xsl:when test="itemMapCode = 11">ClientName</xsl:when>
    <xsl:when test="itemMapCode = 12">ProductCode</xsl:when>
    <xsl:when test="itemMapCode = 13">ProductName</xsl:when>
    <xsl:when test="itemMapCode = 14">JobCode</xsl:when>
    <xsl:when test="itemMapCode = 15">JobName</xsl:when>

    <xsl:when test="itemMapCode = 41">WorkcodeCategory</xsl:when>
    <xsl:when test="itemMapCode = 42">Workcode</xsl:when>
    <xsl:when test="itemMapCode = 43">WorkcodeName</xsl:when>

    <xsl:when test="itemMapCode = 80">CategoryCode</xsl:when>
    <xsl:when test="itemMapCode = 81">CategoryName</xsl:when>

    <xsl:when test="itemMapCode = 90">HeaderText</xsl:when>

  </xsl:choose>
</xsl:variable>

<xsl:if test="$elemName != ''">
  <xsl:element name="{$elemName}">         
    <xsl:value-of select="./itemValue" />
  </xsl:element>
</xsl:if>
<xsl:if test="$elemName = '' and itemMapCode != 1">
  <xsl:message>Warning: no mapping for itemMapCode '<xsl:value-of select="itemMapCode" />'</xsl:message>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

我想要的输出是 -

<EstimateHeader>
  <HeaderText>xxxxxx</HeaderText>
  <HeaderText>yyyy</HeaderText>
</EstimateHeader>

作为替代方案,可以将HeaderText项合并到一个HeaderText标记中吗?

<EstimateHeader>
  <HeaderText>xxxxxx yyyy</HeaderText>
</EstimateHeader>

TIA!

1 个答案:

答案 0 :(得分:1)

最小化示例在这里会更有用。

尝试更改此内容:

<xsl:template match="EstimateDisplayRequest">
<MCSResponse>
  <EstimateDisplayResponse>
    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'M']" />
    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'C']" />

    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'H']" />
    <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'F']" />
  </EstimateDisplayResponse>
</MCSResponse>
</xsl:template>

进入这个:

<xsl:template match="EstimateDisplayRequest">
    <MCSResponse>
        <EstimateDisplayResponse>
            <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'M']" />
            <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'C']" />
            <EstimateHeader>
                <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'H']" />
            </EstimateHeader>
            <xsl:apply-templates select="*/faRecord[item[itemMapCode = 1]/itemValue = 'F']" />
        </EstimateDisplayResponse>
    </MCSResponse>
</xsl:template>

和此:

<xsl:template match="faRecord[item[itemMapCode = 1]/itemValue = 'H']">
<EstimateHeader>
  <xsl:apply-templates select="item" />
</EstimateHeader>
</xsl:template>

进入这个:

<xsl:template match="faRecord[item[itemMapCode = 1]/itemValue = 'H']">
    <xsl:apply-templates select="item" />
</xsl:template>