2013-06-04 45 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>