嗨这是对此处发布的上一个问题的改编。
XSLT - Find element values from first preceding item with matching name id - Using conditionals?
我有一个看起来像下面的XML。
我想创建一个xsl转换,在帖子的底部生成理想的xml。
请注意,在提供的XML中,如果Image节点被多次使用(由其文件ID定义),则其后续子元素不存在。例如,其文件id与第一图像节点相同的第三图像节点不包含子属性和后续值。我想把它们重新加入。
我有下面的当前示例xsl基本上工作但我想在样式表中添加条件评估,其中说: 用英语讲: 如果'key'元素不存在,则找到第一个匹配的'file id'并使用这些元素中的值。这同样适用于'string和'reel'元素。 (在文件节点中弹出的任何其他任何其他内容。
结果将根据匹配文件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>
答案 0 :(得分: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>
答案 1 :(得分: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>