2010-08-25 45 views
0

我的輸入XML文件的樣子檢索XML值動態地使用XSL函數

<root> 
    <sub> 
    <element1 value="abc"/> 
     <element2 value="123"/> 
    </sub> 
    <sub1> 
    <element1 value="ert"/> 
    <element2 value="abc"/> 
    </sub1> 
</root> 

我需要一個XSLT功能讀取下面的XML文件,並拉動以從地圖/域/實例/ @ xpath的指定的xpath表達式值以上文件

<map> 
    <domain> 
    <instance xpath="root/sub/element1/@value" length="2"/> 
    </domain> 
    <domain> 
     <instance xpath="root/sub1/element2/@value" length="3"/> 
    </domain> 
</map> 

我需要一個xslt函數,它檢查每個xpath表達式針對傳入xml文件指定的長度。

如果它的長度失敗,它應該重試false。

回答

3

該XSLT樣式表1.0:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="document"> 
     <root> 
      <sub> 
       <element1 value="abc"/> 
       <element2 value="123"/> 
      </sub> 
      <sub1> 
       <element1 value="ert"/> 
       <element2 value="abc"/> 
      </sub1> 
     </root> 
    </xsl:variable> 
    <xsl:template match="map/domain/instance" name="walker"> 
     <xsl:param name="path" select="@xpath"/> 
     <xsl:param name="context" 
       select="document('')/*/xsl:variable[@name='document']"/> 
     <xsl:choose> 
      <xsl:when test="contains($path,'/')"> 
       <xsl:call-template name="walker"> 
        <xsl:with-param name="path" 
           select="substring-after($path,'/')"/> 
        <xsl:with-param name="context" 
         select="$context/*[name()=substring-before($path,'/')]"/> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:when test="starts-with($path,'@')"> 
       <xsl:value-of select="concat(
             string-length(
              $context/attribute::* 
              [name()=substring($path,2)]) 
             [email protected], 
             '&#xA;')"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="concat(
             string-length(
              $context/*[name()=$path]) 
             [email protected], 
             '&#xA;')"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

false 
true 

編輯:XSLT 2.0溶液。該樣式表:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:my="example.org"> 
    <xsl:output method="text"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:variable name="document"> 
     <root> 
      <sub> 
       <element1 value="abc"/> 
       <element2 value="123"/> 
      </sub> 
      <sub1> 
       <element1 value="ert"/> 
       <element2 value="abc"/> 
      </sub1> 
     </root> 
    </xsl:variable> 
    <xsl:template match="map/domain/instance"> 
     <xsl:sequence select="my:xpath(@xpath,$document) 
            /string(string-length() = 
              current()/@length)"/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 
    <xsl:function name="my:xpath" as="item()*"> 
     <xsl:param name="path" as="xs:string"/> 
     <xsl:param name="context" as="node()*"/> 
     <xsl:variable name="steps" as="item()*" 
         select="tokenize($path,'/')"/> 
     <xsl:variable name="this" as="item()*" 
         select="$context/(*[if ($steps[1]='*') 
              then true() 
              else name()=$steps[1]]| 
             @*[if ($steps[1]='@*') 
              then true() 
              else name() = 
               substring($steps[1],2)])"/> 
     <xsl:choose> 
      <xsl:when test="count($steps)>1"> 
       <xsl:sequence 
        select="my:xpath(string-join($steps[position()!=1], 
               '/'), 
            $this)"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:sequence select="$this"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:function> 
</xsl:stylesheet> 

輸出:

false 
true 

編輯2:一個位improven。所以,現在,這個輸入:

<map> 
    <domain> 
     <instance xpath="root/sub/element1/@*" length="2"/> 
    </domain> 
    <domain> 
     <instance xpath="root/sub/*/@value" length="3"/> 
    </domain> 
</map> 

輸出:

false 
true true 
+0

不壞,@Alejandro! (+1).A – 2010-08-26 01:32:22

+0

@Dimitre:謝謝!我用'$ document'類型打了一下...... – 2010-08-26 13:04:36