XSLT - 取代"价值"元件。条件更新"关键"

时间:2014-06-05 18:57:10

标签: xml xslt

我有一个带PII的XML。

示例XML:

<DictionarySerializer>
  <dictionary xmlns="http://www.kmanage.com/xml/serialization">
    <item>
      <key>FirstName</key>
      <value>John</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">John</value>
      </history>
    </item>
    <item>
      <key>FirstName</key>
      <value>John</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">John</value>
      </history>
    </item>
    <item>
      <key>MiddleName</key>
      <value>quo</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">quo</value>
      </history>
    </item>
    <item>
      <key>LastName</key>
      <value>Dou</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">Dou</value>
      </history>
    </item>
  </dictionary>
</DictionarySerializer>

我需要变换“value”元素。条件重播“密钥”

我的XSLT用于替换一个“键”的“值”:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:doc="http://www.kmanage.com/xml/serialization">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

 <xsl:template match="doc:item[doc:key/text() = 'FirstName']/doc:value/text()">
   <xsl:text>********</xsl:text>
 </xsl:template>
</xsl:stylesheet>

如果“key”等于FirstName,LastName,DateOfBirth,Passport等,我需要替换“value”...

我的结果:

<DictionarySerializer>
  <dictionary xmlns="http://www.kmanage.com/xml/serialization">
    <item>
      <key>FirstName</key>
      <value>********</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">John</value>
      </history>
    </item>
    <item>
      <key>FirstName</key>
      <value>********</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">John</value>
      </history>
    </item>
    <item>
      <key>MiddleName</key>
      <value>quo</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">quo</value>
      </history>
    </item>
    <item>
      <key>LastName</key>
      <value>Dou</value>
      <type>String</type>
      <history>
        <value stamp="201405301854095003707" owner="admin" type="String">Dou</value>
      </history>
    </item>
  </dictionary>
</DictionarySerializer>

如何在不使用数组的情况下执行此操作?

问候,伊利亚

4 个答案:

答案 0 :(得分:1)

假设您想要平等对待所有键,您可以使用:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:doc="http://www.kmanage.com/xml/serialization">

  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="doc:item[doc:key = 'FirstName' or doc:key = 'LastName' or doc:key = 'DateOfBirth' or doc:key = 'Passport' or doc:key = 'and so on...']/doc:value/text()">
    <xsl:text>********</xsl:text>
  </xsl:template>
</xsl:stylesheet>

虽然我个人更喜欢为这些东西创建一个查找表。您可以使用exslt:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:doc="http://www.kmanage.com/xml/serialization"
                xmlns:exsl="http://exslt.org/common">

    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="keysXml">
        <keys>
            <key>FirstName</key>
            <key>LastName</key>
            <key>DateOfBirth</key>
            <!-- add all required keys here -->
        </keys>
    </xsl:variable>
    <xsl:variable name="keys" select="exsl:node-set($keysXml)/keys" />

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

    <xsl:template match="doc:value">
        <xsl:choose>
            <xsl:when test="$keys/key = ../doc:key">
                <xsl:copy>
                    <xsl:text>********</xsl:text>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

这样你需要做的就是为另一个键添加另一个条目,这使得可维护性变得更加容易。

答案 1 :(得分:0)

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.kmanage.com/xml/serialization">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
 <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
 </xsl:copy>
 </xsl:template>
 <xsl:template match="doc:item[doc:key/text() = 'FirstName']/doc:value/text()">
 <xsl:text>********</xsl:text>
 </xsl:template>
 <xsl:template match="doc:item[doc:key/text() = 'LastName']/doc:value/text()">
 <xsl:text>******** lastName replacement</xsl:text>
 </xsl:template>
 </xsl:stylesheet>

答案 2 :(得分:0)

此样式表会过滤出匹配列表的value的{​​{1}}:

key

您可以通过将过滤后的密钥列表存储在变量中并使用XPath的<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="http://www.kmanage.com/xml/serialization" version="1.0"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="doc:value/text()"> <xsl:variable name="associated-key" select="../preceding-sibling::doc:key/text()"/> <xsl:choose> <xsl:when test="$associated-key = 'FirstName' or $associated-key = 'LastName' or $associated-key = 'DateOfBirth'">********</xsl:when> <xsl:otherwise> <xsl:value-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> 函数来查看当前密钥是否匹配来消除更多优雅。

答案 3 :(得分:0)

如果要维护样式表中的PII键列表,则可以指定键名称的分隔列表并测试doc:key的值(带有分隔符的连接作为前缀和后缀) (以避免键名称的部分匹配)包含在分隔的PII键列表中。

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:doc="http://www.kmanage.com/xml/serialization">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="doc:item[contains(
                                   '|FirstName|LastName|DateOfBirth|Passport|',
                                    concat('|', doc:key, '|') 
                                   )]/doc:value/text()">
        <xsl:text>********</xsl:text>
    </xsl:template>
</xsl:stylesheet>