1

嗨,这是对此处发布的先前问题的改编。

XSLT - 从具有匹配名称 id 的前一项中查找元素值 - 使用条件?

我有一个如下所示的 XML。

我想创建一个 xsl 转换,在帖子底部生成理想的 xml。

请注意,在呈现的 XML 中,如果多次使用 Image 节点(由其文件 id 定义),则不存在其后续子元素。例如第三个图像节点,其文件 id 与第一个图像节点相同,不包含子属性和后续值。我想重新添加它们。

我有下面的当前示例 xsl,它基本上可以正常工作,但我想在样式表中添加一个条件评估,上面写着:用英语:如果 'key' 元素不存在,则查找前面的第一个匹配的 'file id' 并使用这些元素的值。这同样适用于“字符串”和“卷轴”元素。(在文件节点中弹出的任何其他内容。

结果将根据匹配文件 id 的第一个实例用所有相关数据填充空文件节点。

为我糟糕的描述道歉。

任何帮助将不胜感激。

XML:

<?xml version="1.0"?>
<xmeml>
<boxset>
<stream>
    <track>
        <image>
            <start>0</start>
            <end>90</end>
            <file id="abcde">
                <key>95</key>
                <string>1023</string>
                <time>
                    <reel>142</reel>
                </time>
            </file>
        </image>
        <image>
            <start>90</start>
            <end>120</end>
            <file id="bcdef">
                <key>55</key>
                <string>1023</string>
                <time>
                    <reel>64</reel>
                </time>
            </file>
        </image>
    </track>
    <track>
        <image>
            <start>120</start>
            <end>130</end>
            <file id="abcde"/>
        </image>
        <image>
            <start>130</start>
            <end>180</end>
            <file id="cdefg">
                <key>92</key>
                <string>1023</string>
                <time>
                    <reel>194</reel>
                </time>
            </file>
        </image>    
    </track>
</stream>
</boxset>
</xmeml>

XSLT:标准身份转换

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


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

</xsl:stylesheet>

如果要填充 XML,他们希望看到它看起来像这样。

理想的 XML:

<?xml version="1.0"?>
<xmeml>
<boxset>
<stream>
    <track>
        <image>
            <start>0</start>
            <end>90</end>
            <file id="abcde">
                <key>95</key>
                <string>1023</string>
                <time>
                    <reel>142</reel>
                </time>
            </file>
        </image>
        <image>
            <start>90</start>
            <end>120</end>
            <file id="bcdef">
                <key>55</key>
                <string>1023</string>
                <time>
                    <reel>64</reel>
                </time>
            </file>
        </image>
    </track>
    <track>
        <image>
            <start>120</start>
            <end>130</end>
<!-- ideal data for repeated file "abcde" -->
            <file id="abcde">
                <key>95</key>
                <string>1023</string>
                <time>
                    <reel>142</reel>
                </time>
            </file>
<!-- end ideal repeated data -->
        </image>
        <image>
            <start>130</start>
            <end>180</end>
            <file id="cdefg">
                <key>92</key>
                <string>1023</string>
                <time>
                    <reel>194</reel>
                </time>
            </file>
        </image>    
    </track>
</stream>
</boxset>
</xmeml>
4

2 回答 2

1

这种转变

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

 <xsl:key name="kImageById" match="image" use="file/@id"/>

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

 <xsl:template match=
  "image[not(generate-id()
            =generate-id(key('kImageById',file/@id)[1])
            )]">
  <xsl:copy>
   <xsl:apply-templates select="@*|start|end"/>
   <xsl:apply-templates select=
   "key('kImageById',file/@id)[1]/*[not(self::start or self::end)]"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<xmeml>
    <boxset>
        <stream>
            <track>
                <image>
                    <start>0</start>
                    <end>90</end>
                    <file id="abcde">
                        <key>95</key>
                        <string>1023</string>
                        <time>
                            <reel>142</reel>
                        </time>
                    </file>
                </image>
                <image>
                    <start>90</start>
                    <end>120</end>
                    <file id="bcdef">
                        <key>55</key>
                        <string>1023</string>
                        <time>
                            <reel>64</reel>
                        </time>
                    </file>
                </image>
            </track>
            <track>
                <image>
                    <start>120</start>
                    <end>130</end>
                    <file id="abcde"/>
                </image>
                <image>
                    <start>130</start>
                    <end>180</end>
                    <file id="cdefg">
                        <key>92</key>
                        <string>1023</string>
                        <time>
                            <reel>194</reel>
                        </time>
                    </file>
                </image>
            </track>
        </stream>
    </boxset>
</xmeml>

产生想要的正确结果:

<xmeml>
   <boxset>
      <stream>
         <track>
            <image>
               <start>0</start>
               <end>90</end>
               <file id="abcde">
                  <key>95</key>
                  <string>1023</string>
                  <time>
                     <reel>142</reel>
                  </time>
               </file>
            </image>
            <image>
               <start>90</start>
               <end>120</end>
               <file id="bcdef">
                  <key>55</key>
                  <string>1023</string>
                  <time>
                     <reel>64</reel>
                  </time>
               </file>
            </image>
         </track>
         <track>
            <image>
               <start>120</start>
               <end>130</end>
               <file id="abcde">
                  <key>95</key>
                  <string>1023</string>
                  <time>
                     <reel>142</reel>
                  </time>
               </file>
            </image>
            <image>
               <start>130</start>
               <end>180</end>
               <file id="cdefg">
                  <key>92</key>
                  <string>1023</string>
                  <time>
                     <reel>194</reel>
                  </time>
               </file>
            </image>
         </track>
      </stream>
   </boxset>
</xmeml>
于 2012-08-10T02:43:30.477 回答
0

我认为只处理file而不用担心会更简单image

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

  <xsl:key name="file" match="file[*]" use="@id"/>

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

  <xsl:template match="file[not(*)]">
    <xsl:copy-of select="key('file', @id)" />
  </xsl:template>

</xsl:stylesheet>
于 2012-08-10T11:56:45.133 回答