gpt4 book ai didi

xml - 复制 xslt 应用模板中不存在的剩余元素

转载 作者:行者123 更新时间:2023-12-04 04:48:01 24 4
gpt4 key购买 nike

我是 xslt 的新手并面临一个问题。我必须使用 xslt 根据预定义的顺序对 xml 文件中的元素重新排序。通过使用 xsl:copy-of 或 xsl:apply-template 并重新排序元素,我成功地做到了这一点。但是,如果源 xml 有一些 xslt 应用模板中不存在的新元素,那么这些新元素就不会被复制。就像在下面的例子中一样,元素“State”在输出中丢失了。

例如。原始xml

<Company>
<Employee id="100" Name="John" >
<Salary value="15000"/>
<Qualification text="Engineering">
<State name="Kerala" code="02">
<Background text="Indian">
</Employee>
</Company>

XSLT 按 Qualification 、 Salary 和 Background 的顺序对元素重新排序
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output indent="yes" omit-xml-declaration="yes" method="xml" />
<xsl:strip-space elements="*"/>

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

<xsl:template match="Employee">
<xsl:copy>
<xsl:apply-templates select="Qualification"/>
<xsl:apply-templates select="Salary" />
<xsl:apply-templates select="Background"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

获得的输出
<?xml version="1.0" encoding="utf-8"?>
<Company>
<Employee>
<Qualification text="Engineering" />
<Salary value="15000" />
<Background text="Indian" />
</Employee>
</Company>

需要输出
<?xml version="1.0" encoding="utf-8"?>
<Company>
<Employee>
<Qualification text="Engineering" />
<Salary value="15000" />
<Background text="Indian" />
<State name="Kerala" code="02"/>
</Employee>
</Company>

请告诉我 xslt 如何在现有标签的重新排序完成后自动复制任何剩余的新标签。

最佳答案

  <xsl:template match="Employee">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="Qualification"/>
<xsl:apply-templates select="Salary" />
<xsl:apply-templates select="Background"/>
<xsl:apply-templates select="node()[
not(self::Qualification | self::Salary | self::Background)]" />
</xsl:copy>
</xsl:template>

这将首先复制属性,然后按固定顺序复制您感兴趣的特定元素,最后复制除这三个元素之外的所有其他元素。省略第一个 apply-templates ( @* 一个)如果你想复制 Employee没有其属性的标签。

编辑:您在评论中说,即使在重新排序之后,您也希望将任何评论保留在相关元素之上。我能想到的最有效的方法是使用 key 。在样式表的顶层(在任何模板之外)定义它:
<xsl:key name="elementPreamble" match="text()|comment()|processing-instruction()"
use="generate-id(following-sibling::*[1])" />

给定任何元素节点,这提供了一种有效地提取出现在此元素的开始标记和前一个结束标记(或此元素的开始标记及其父级的开始标记,如果这是)之间的所有非元素节点的方法其父元素的第一个子元素)。样式表然后变成:
<?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" omit-xml-declaration="yes" method="xml" />
<xsl:strip-space elements="*"/>

<xsl:key name="elementPreamble" match="text()|comment()|processing-instruction()"
use="generate-id(following-sibling::*[1])" />

<xsl:template match="/">
<!-- Only process the root _element_, not any root-level comments etc.
Without this template any comments ahead of the root element would be
doubled in the output -->
<xsl:apply-templates select="*" />
</xsl:template>

<xsl:template match="@*|text()|comment()|processing-instruction()">
<xsl:copy/>
</xsl:template>

<xsl:template match="*">
<!-- any preamble for this element -->
<xsl:apply-templates select="key('elementPreamble', generate-id())" />
<xsl:copy>
<xsl:apply-templates select="@* | *" />
<!-- any "post-amble" between the last child element (if any) and this
element's own closing tag -->
<xsl:apply-templates select="(text()|comment()|processing-instruction())[
not(following-sibling::*)]" />
</xsl:copy>
</xsl:template>

<xsl:template match="Employee">
<xsl:copy>
<xsl:apply-templates select="Qualification"/>
<xsl:apply-templates select="Salary" />
<xsl:apply-templates select="Background"/>
<!-- other elements -->
<xsl:apply-templates select="*[
not(self::Qualification | self::Salary | self::Background)]" />
<!-- "post-amble" -->
<xsl:apply-templates select="(text()|comment()|processing-instruction())[
not(following-sibling::*)]" />
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

鉴于输入
<!-- Details of the company's employees -->
<Company>
<Employee id="100" Name="John" >
<!-- salary -->
<!-- check this with HR -->
<Salary value="15000"/>
<Qualification text="Engineering"/>
<!-- the employee's home state -->
<State name="Kerala" code="02"/>
<!-- the employee's background -->
<Background text="Indian"/>
<!-- this is the end of the record -->
</Employee>
</Company>

这个样式表产生输出
<!-- Details of the company's employees -->
<Company>
<Employee>
<Qualification text="Engineering"/>
<!-- salary -->
<!-- check this with HR -->
<Salary value="15000"/>
<!-- the employee's background -->
<Background text="Indian"/>
<!-- the employee's home state -->
<State name="Kerala" code="02"/>
<!-- this is the end of the record -->
</Employee>
</Company>

注释仍然附加到它们最近的后续元素,其顺序与它们在输入文档中出现的顺序相同。

关于xml - 复制 xslt 应用模板中不存在的剩余元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17888642/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com