Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
869 views
in Technique[技术] by (71.8m points)

dynamic xpath in xslt?

I have follwing set of files:

SourceFile.xml:

      <?xml version="1.0" encoding="utf-8" ?>
     <Employees>
     <Employee id="1">
          <firstname relationship="headnote">Atif</firstname>
          <lastname relationship="lname">Bashir</lastname>
          <age relationship="age">32</age>
          </Employee>
     </Employees>

ParamerterSettings.xml

        <?xml version="1.0" encoding="utf-8"?>
        <Settings>
        <Employee id="1">
             <sourceFile>Lookup1.xml</sourceFile>
             <sourceXpathfield>Employees/Employee[@id</sourceXpathfield>
             <lookupXpathfield>Employees/Employee[@id='1']</lookupXpathfield>
             <elementstoinsert>xyz</elementstoinsert>
             </Employee>
         </Settings>

Lookup.xml

<?xml version="1.0" encoding="utf-8"?>
 <Employees>
  <Employee id="1">
      <department code="102">HR</department>
   </Employee>
   </Employees>

transform.xsl

  <?xml version="1.0" encoding="UTF-8" ?>
   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

   <xsl:include href="identity.xsl"/>

  <xsl:param name="EmployeeId" select="'1,2'" />
  <xsl:variable name="FileSettings" select="document('test3.xml')" />
  <xsl:variable name="SuppressSetting" select="$FileSettings/Settings/Employee[@id = tokenize($EmployeeId, ',')]" />

  <xsl:template match="Employee">
  <xsl:copy>
  <xsl:apply-templates select="@*"/>
  <xsl:apply-templates select="publisher" />
  <xsl:apply-templates select="node() except publisher"/>
  <xsl:variable name="outerfile" select="document($SuppressSetting/sourceFile)"></xsl:variable>
  <xsl:variable name="outerfiledetails" select="$outerfile/$SuppressSetting/lookupXpathfield"></xsl:variable>
  <xsl:value-of select="$outerfiledetails"></xsl:value-of>
</xsl:copy>
</xsl:template>

</xsl:stylesheet> 

The output should be:

     <?xml version="1.0" encoding="utf-8" ?>
     <Employees>
     <Employee id="1">
          <firstname relationship="headnote">Atif</firstname>
          <lastname relationship="lname">Bashir</lastname>
          <age relationship="age">32</age>
          HR
          </Employee>
     </Employees>

I changed the below line in Transform.xsl

<xsl:variable name="outerfiledetails" select="$outerfile/$SuppressSetting/lookupXpathfield"></xsl:variable>

into

<xsl:variable name="outerfiledetails" select="$outerfile/Employees/Employee[@id='1']"></xsl:variable>

then I am getting my output but I want to keep the XPath epression for both SourceFile.xml and Lookup.xml into ParamerterSettings.xml so that I can write a more generic script. Can this be done in any other way then the dynamic xpath? Any idea or hint to impelement the same will be highly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Dynamic XPath evaluation is not possible in pure XSLT 1.0 or 2.0.

There are at least three ways to do this in a "hybrid" solution:

I. Use the EXSLT function dyn:evaluate()

Unfortunately, very few XSLT 1.0 processors implement dyn:evaluate().

II. Process the XML document with XSLT and generate a new XSLT file that contains the XPath expressions -- then execute the newly-generated transformation.

Very few people do this and, in my opinion, this is more complex than the next solution.

III. The way the XPath Visualizer works

The idea is:

  1. Have a global variable in the XSLT stylesheet defined like this:

      <xsl:variable name="vExpression" select="dummy"/>
    
  2. Then, load the stylesheet as an XML document using DOM, and replace the select attribute of the vExpression variable with the actual XPath expression that is contained in the source XML document.

  3. Finally, initiate the transformation using the loaded into memory and dynamically updated xslt stylesheet.


IV. With XSLT 3.0

Use the <xsl:evaluate> instruction


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...