繁体   English   中英

使用XSLT 2.0动态替换XML中的属性或元素值

[英]Dynamically replace attribute or element values in XML using XSLT 2.0

我有一个XML

<?xml version="1.0" encoding="utf-8"?>
<CATALOG>
    <PLANT COLOR="@DYNAMIC_COLOR@">
        <COMMON>Bloodroot</COMMON>
        <BOTANICAL>Sanguinaria canadensis</BOTANICAL>
        <ZONE>4</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>@DYNAMIC_PRICE@</PRICE>
        <AVAILABILITY>031599</AVAILABILITY>
    </PLANT>
    <PLANT COLOR="RED" TYPE="@DYNAMIC_TYPE@">
        <COMMON>Columbine</COMMON>
        <BOTANICAL>Aquilegia canadensis</BOTANICAL>
        <ZONE>3</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>$9.37</PRICE>
        <AVAILABILITY>030699</AVAILABILITY>
    </PLANT>
</CATALOG>

我想转变成

<?xml version="1.0" encoding="utf-8"?>
<CATALOG>
    <PLANT COLOR="RED">
        <COMMON>Bloodroot</COMMON>
        <BOTANICAL>Sanguinaria canadensis</BOTANICAL>
        <ZONE>4</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>10</PRICE>
        <AVAILABILITY>031599</AVAILABILITY>
    </PLANT>
    <PLANT COLOR="RED" TYPE="HERBS">
        <COMMON>Columbine</COMMON>
        <BOTANICAL>Aquilegia canadensis</BOTANICAL>
        <ZONE>3</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>$9.37</PRICE>
        <AVAILABILITY>030699</AVAILABILITY>
    </PLANT>
</CATALOG>

基本上,我想用预定义值替换“ @DYNAMIC _ * @”属性/元素值。 请帮忙!!! 我可以针对每个对象进行精确查找,然后将其替换为所需的值。 但是我更喜欢使用Apply模板的概念。

解决此类问题的一个好办法是将您的框架XML文档转换为样式表。 编写将其转换为的转换:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" expand-text="yes">
  <xsl:param name="DYNAMIC_COLOR"/>
  <xsl:param name="DYNAMIC_TYPE"/>
  <xsl:template name="xsl:initial-template">
<CATALOG>
    <PLANT COLOR="{$DYNAMIC_COLOR}">
        <COMMON>Bloodroot</COMMON>
        <BOTANICAL>Sanguinaria canadensis</BOTANICAL>
        <ZONE>4</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>{$DYNAMIC_PRICE}</PRICE>
        <AVAILABILITY>031599</AVAILABILITY>
    </PLANT>
    <PLANT COLOR="RED" TYPE="{$DYNAMIC_TYPE}">
        <COMMON>Columbine</COMMON>
        <BOTANICAL>Aquilegia canadensis</BOTANICAL>
        <ZONE>3</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>$9.37</PRICE>
        <AVAILABILITY>030699</AVAILABILITY>
    </PLANT>
</CATALOG>
  </xsl:template>
</xsl:stylesheet>

然后使用入口点“ xsl:initial-template”和参数值执行此样式表。 我在这里使用了XSLT 3.0值模板,使其变得更容易了。 如果要使用XSLT 2.0,则可以生成xsl:value-of指令。

转换的基本逻辑是

<xsl:stylesheet ...>
<xsl:namespace-alias stylesheet-prefix="z" result-prefix="xsl"/>
<xsl:variable name="params" select="distinct-values(
     (//@*|//text())[matches(., '^@.*@^')]!translate(., '@', ''))"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="/">
  <z:stylesheet version="3.0" expand-text="yes">
    <xsl:for-each select="$params">
      <z:param name="{.}"/>
    </xsl:for-each>
    <z:template name="xsl:initial-template">          
      <xsl:apply-templates/>
    </z:template>
  </z:stylesheet>
</xsl:template>

<xsl:template match="@*[matches(., '^@.*@$')]">
  <xsl:attribute name="{name()}" select="replace(., '^@(.*)@$', '{\$$1}')"/>
</xsl:template>

<xsl:template match="text()[matches(., '^@.*@$')]">
  <!-- 3.0 -->
  <!-- <xsl:value-of select="replace(., '^@(.*)@$', '{\$$1}')"/> -->
  <!-- 2.0 -->
  <z:value-of select="replace(., '^@(.*)@$', '\$$1'"/>
</xsl:template>

</xsl:stylesheet>

如果某些属性或文本节点包含花括号,则可能需要做更多的工作:这需要加倍。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM