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

时间:2019-02-14 08:37:47

标签: xml xslt

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

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

这是我的源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 个答案:

答案 0 :(得分:0)

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

  1. 匹配TextSymbols的模板应:

    • 身份模板一样应用模板。
    • 然后再次应用模板,但仅适用于TextSymbol SymbolKey以“特殊”(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