2013-06-04 46 views
0

我有一个外部文件,像这样多的Xpath的列表:使用动态匹配的XSLT

<EncrypRqField> 
    <EncrypFieldRqXPath01>xpath1</EncrypFieldRqXPath01> 
    <EncrypFieldRqXPath02>xpath2</EncrypFieldRqXPath02> 
</EncrypRqField> 

我使用这个文件来获得我想要修改的节点的Xpath。

输入XML是:

<Employees> 
    <Employee> 
     <id>1</id> 
     <firstname>xyz</firstname> 
     <lastname>abc</lastname> 
     <age>32</age> 
     <department>xyz</department> 
    </Employee> 
</Employees> 

我想获得这样的事:

<Employees> 
    <Employee> 
     <id>XXX</id> 
     <firstname>xyz</firstname> 
     <lastname>abc</lastname> 
     <age>XXX</age> 
     <department>xyz</department> 
    </Employee> 
</Employees> 

的XXX值的数据加密的结果,我想从动态获取的Xpath该文档并更改其节点的值。

谢谢。

回答

0

我不确定在XSL 2.0中是否可以这样做。可能在3.0应该有一些函数评估(),但我不知道任何细节。

但我尝试了一些解决方法,它似乎是功能。当然,这并不完美,并且在这种形式中有许多限制(例如,您需要指定绝对路径,不能使用更复杂的XPath,比如//,[]等),因此将其视为一个想法。但这可能是一些更简单的情况。

它是基于比较两个字符串而不是评估字符串作为XPath。

简化XML与xpaths加密(为简单起见,我省略了数字)。

<?xml version="1.0" encoding="UTF-8"?> 
<EncrypRqField> 
    <EncrypFieldRqXPath>/Employees/Employee/id</EncrypFieldRqXPath> 
    <EncrypFieldRqXPath>/Employees/Employee/age</EncrypFieldRqXPath> 
</EncrypRqField> 

我的转型

<xsl:template match="element()"> 
     <xsl:variable name="pathToElement"> 
      <xsl:call-template name="getPath"> 
       <xsl:with-param name="element" select="." /> 
      </xsl:call-template> 
     </xsl:variable> 

     <xsl:choose> 
      <xsl:when test="$xpaths/EncrypFieldRqXPath[text() = $pathToElement]"> 
       <!-- If exists element with exacty same value as constructed "XPath", ten "encrypt" the content of element --> 
       <xsl:copy> 
        <xsl:text>XXX</xsl:text> 
       </xsl:copy> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:apply-templates /> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <!-- This template will "construct" the XPath for element under investigation. --> 
    <!-- There might be an easier way (e.g. some build-in function), but it is actually out of my skill. --> 
    <xsl:template name="getPath"> 
     <xsl:param name="element" /> 
     <xsl:choose> 
      <xsl:when test="$element/parent::node()"> 
       <xsl:call-template name="getPath"> 
        <xsl:with-param name="element" select="$element/parent::node()" /> 
       </xsl:call-template> 
       <xsl:text>/</xsl:text> 
       <xsl:value-of select="$element/name()" /> 
      </xsl:when> 
      <xsl:otherwise /> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet>