通过xslt一步复制和操作xml元素

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过xslt一步复制和操作xml元素相关的知识,希望对你有一定的参考价值。

我想复制xml的一些部分(在标准之间)并在一步中操作复制部分中的一些值。这是应该做的:

  1. 寻找TextSymbol [SymbolKey> = 2000 AND <= 3000]
  2. 复制匹配的节点TextSymbol
  3. 更新复制节点中SymbolKey的值,前缀为92

这是我的源码xml:

<?xml version="1.0" encoding="UTF-8"?>
<TextSymbols>
    <TextSymbol>
        <SymbolKey>1000</SymbolKey>
        <Name>PHY</Name>
    </TextSymbol>
    <TextSymbol>
        <SymbolKey>2000</SymbolKey>
        <Name>LEX</Name>
    </TextSymbol>
    <TextSymbol>
        <SymbolKey>3000</SymbolKey>
        <Name>TIR</Name>
    </TextSymbol>
</TextSymbols>

目标是:

<?xml version="1.0" encoding="UTF-8"?>
<TextSymbols>
    <TextSymbol>
        <SymbolKey>1000</SymbolKey>
        <Name>PHY</Name>
    </TextSymbol>
    <TextSymbol>
        <SymbolKey>2000</SymbolKey>
        <Name>LEX</Name>
    </TextSymbol>
    <TextSymbol>
        <SymbolKey>3000</SymbolKey>
        <Name>TIR</Name>
    </TextSymbol>
    <TextSymbol>
        <SymbolKey>922000</SymbolKey>
        <Name>LEX</Name>
    </TextSymbol>
    <TextSymbol>
        <SymbolKey>923000</SymbolKey>
        <Name>LEX</Name>
    </TextSymbol>
</TextSymbols>

提前致谢

答案

您应该按以下方式编写脚本:

  1. 模板匹配TextSymbols应该: 像身份模板一样应用模板。 然后再次应用模板,但仅适用于TextSymbolSymbolKey在“特殊”(prepend)模式下的所需范围内。
  2. SymbolKey模式下应该有一个匹配prepend的模板,它写入输出“92”(字符串前置)然后它自己的值。
  3. 以及身份模板的另外两个扩展。这应该: 在所有模式下执行(mode="#all)。 包含的apply-templates应保持当前模式(mode="#current"

所以整个脚本可能如下所示:

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

  <xsl:template match="TextSymbols">
    <xsl:copy>
      <xsl:apply-templates/>
      <xsl:apply-templates mode="prepend"
        select="TextSymbol[number(SymbolKey) ge 2000 and number(SymbolKey) le 3000]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="SymbolKey" mode="prepend">
    <xsl:copy><xsl:value-of select="concat('92', .)"/></xsl:copy>
  </xsl:template>

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

有关工作示例,请参阅http://xsltransform.net/gVAjbSY

并附有关于您预期结果的说明:

你没有写任何关于改变Name元素内容的东西,所以我假设最后一个输出TextSymbol中的这个元素应该是TIR(就像在输入中),而不是LEX

以上是关于通过xslt一步复制和操作xml元素的主要内容,如果未能解决你的问题,请参考以下文章

使用命名空间时无法在 XSLT 中复制和修改属性

有没有办法使用 XSLT 基于 XML 中的元素复制 XML 节点 n 次?

有没有办法使用 XSLT 基于 XML 中的元素复制 XML 节点 n 次?

如何使用 xslt 将父节点命名空间复制到子元素?

将 XSLT 转换的 XML 片段写入 XMLStreamWriter

XSLT 转换从混合内容中删除 HTML 元素