Populate XML template-file from XPath Expressions?

后端 未结 2 852
离开以前
离开以前 2021-01-03 11:16

What would be the best way to populate (or generate) an XML template-file from a mapping of XPath expressions?

The requirements are that we will need to start with a

2条回答
  •  生来不讨喜
    2021-01-03 12:04

    This solution requires you to re-organise your XPATH input information slightly, and to allow a 2-step transformation. The first transformation will write the stylesheet, which will be executed in the second transformation - Thus the client is required to do two invocations of the XSLT engine. Let us know if this is a problem.

    Step One

    Please re-organise your XPATH information into an XML document like so. It should not be difficult to do, and even an XSLT script could be written to do the job.

    
     
      article[1]/id[1]
      
       http://predic8.com/wsdl/material/ArticleService/1/
       
      
      1
      
     
      article[1]/description[1]
      
      bar
     
     ... etc ...
    
    

    Solution constraints

    In the above rules document we are constrained so that:

    1. The match is implicitly prefixed 'expression: /create/'. Don't put that explicitly.
    2. All matches must begin like article[n] where n is some ordinal number.
    3. We can't have zero rules.
    4. Any prefixes that you use in the match, other than s11="http://schemas.xmlsoap.org/soap/envelope/" and ns1="http://predic8.com/wsdl/material/ArticleService/1/". (Note: I don't think it is valid for namespaces to end in '/' - but not sure about that), are defined in the namespaces node.

    The above is the input document to the step one transformation. Apply this document to this style-sheet ...

    
    
    
    
    
     
     
    
      
       
      
    
      
         
            
         
      
    
      
         
        
       
           
            
           
             
             
      
    
      
       
        
       
       
    
      
       
      
    
       
     
    
    
    
     
      
       
      
      
       
       
       
      
     
    
    
    
    

    Step Two

    Apply your soap envelope file, as an input document, to the style-sheet which was output from step one. The result is the original soap document, altered as required. This is a sample of a step two style-sheet, with just the first rule (/create/article[1]/id => 1) being considered for the sake of simplicity of illustration.

    
    
       
       
          
             
          
       
       
          
             
             
             
          
       
    
    

    More solution constraints

    1. The template document must contain at least one /s11:Envelope/s11:Body/ns1:create/article . Only the article node is replicated (deeply) as required by rules. Other than than it can be any structure.
    2. The template document cannot contain nested levels of the s11:Envelope/s11:Body/ns1:create node.

    Explanation

    You will notice that your XPATH expressions are not far removed from a match condition of template. Therefore it is not too difficult to write a stylesheet which re-expresses your XPATH and replacement values as template rules. When writing a style-sheet writing style-sheet the xsl:namespace-alias enables us to disambiguate "xsl:" as an instruction and "xsl:" as intended output. When XSLT 3.0 comes along, we are quiet likely to be able to reduce this algorithm into one step, as it will allow dynamic XPATH evaluation, which is really the nub of your problem. But for the moment we must be content with a 2-step process.

    The second style-sheet is a two-phase transformation. The first stage replicates the template from the article level, as many times as needed by the rules. The second phase parses this replicated template, and applies the dynamic rules substituting text values as indicated by the XPATHs.


    UPDATE

    My original post was wrong. Thanks to Dimitre for pointing out the error. Please find updated solution above.

    After-thought

    If a two-step solultion is too complicated, and you are running on a wintel platform, you may consider purchasing the commercial version of Saxon. I believe that the commercial version has a dynamic XPATH evaluation function. I can't give you such a solution because I don't have the commercial version. I imagine a solution using an evaluate() function would be a lot simpler. XSLT is just a hobby for me. But if you are using XSLT for business purposes, the price is quiet reasonable.

提交回复
热议问题