繁体   English   中英

Xslt – xsl:with-param 动态分配(正确使用 xsl:with-param 没有 select 属性)

[英]Xslt – xsl:with-param dynamically assigned (Correct usage of xsl:with-param without select attribute)

我有以下 XML

<Envelope>
    <Records>
        <Record>
            <Information>
                <Value>TEST INTERNAL VALUE</Value>
            </Information>
        </Record>
        <Record>
            <Information id="123456"/>
        </Record>
        <Information id="123456">
            <Value>TEST REFERENCE VALUE</Value>
        </Information>
    </Records>
</Envelope>

每个记录元素可以有一个或多个 Information 元素,该元素可以有一个 Value 元素,可以有一个 ref 属性,该属性包含一个 ID,该 ID 指向当前记录元素之外的一个单独的 Information 元素

使用转换表,我想遍历每个记录元素,遍历每个信息元素,然后如果信息元素具有 id 属性,则使用该属性到 select 通过相同属性记录下的信息并提供结果 select到模板或只是将当前选择的信息元素提供给模板

到目前为止,我有这张转换表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template name="EOL">
<xsl:text>
</xsl:text>
    </xsl:template>
    <xsl:template match="/">
        <xsl:for-each select="//Records">
            <xsl:call-template name="Records_Template">
                <xsl:with-param name="Records" select="."/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="Records_Template">
        <xsl:param name="Records"/>
        <xsl:for-each select="Record">
            <xsl:call-template name="EOL"/>
            <xsl:text>Result - using template (Both Record):</xsl:text>
            <xsl:call-template name="EOL"/>
            <xsl:for-each select="Information">
                <xsl:variable name="InformationRef" select="@id"/>
                <xsl:call-template name="Information_Template">
                    <xsl:with-param name="Information">
                        <xsl:choose>
                            <xsl:when test="$InformationRef">
                                <xsl:copy-of select="$Records/Information[@id=$InformationRef]"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:copy-of select="."/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="Information_Template">
        <xsl:param name="Information"/>
        <!--This is for debugging purposes. It indicates that in each case, the content of Information parameter is the same regardless of how Information was set using with-param -->
        <xsl:text>Full Start: </xsl:text>
        <xsl:call-template name="EOL"/>
        <xsl:copy-of select="$Information"/>
        <xsl:text>Full END: </xsl:text>
        <xsl:call-template name="EOL"/>
        <xsl:text>Value: </xsl:text>
        <!--Even though $Information and $Information/Value do seem to be populated as per the debugging information above This selection statement does not seem to work -->
        <xsl:value-of select="$Information/Value"/>
        <xsl:call-template name="EOL"/>
    </xsl:template>
</xsl:stylesheet>

Transformation Sheet的output如下:

Result - using template (Both Record):
Full Start: 
<Information>
                <Value>TEST INTERNAL VALUE</Value>
            </Information>Full END: 
Value: 

Result - using template (Both Record):
Full Start: 
<Information id="123456">
            <Value>TEST REFERENCE VALUE</Value>
        </Information>Full END: 
Value: 

应该注意的是,如果我这样调用 Information_Template:

<xsl:call-template name="Information_Template">
    <xsl:with-param name="Information" select="$Records/Information[@id=$InformationRef]"/>
</xsl:call-template>

或者像这样

<xsl:call-template name="Information_Template">
    <xsl:with-param name="Information" select="."/>
</xsl:call-template>

那么模板就能够 select 的 Value 元素的内容。

编辑:添加更多细微差别。

转换的 output 是 Text 并围绕 Record 元素旋转。 每个 Record 元素将有多个子元素 function 与 Information 元素相同。 output 需要为每个记录生成信息,其中只包含与记录相关的信息所以这个:

<Envelope>
   <Records>
       <Record>
           <Information>
               <Value>TEST INTERNAL VALUE 1</Value>
           </Information>
           <Person>
               <name>Test Name 1</name>
           </Person>
       </Record>
       <Record>
           <Information id="123456"/>
           <Person id="67890"/>
       </Record>
       <Record>
           <Information id="654321"/>
           <Person id="09876"/>
       </Record>
       <Information id="123456">
           <Value>TEST REFERENCE VALUE 2</Value>
       </Information>
       <Information id="654321">
           <Value>TEST REFERENCE VALUE 3</Value>
       </Information>
       <Person id="67890">
           <name>Test Name 2</name>
       </Person>
       <Person id="09876">
           <name>Test Name 3</name>
       </Person>
   </Records>
</Envelope>

需要转换为:

===Record====
Name: Test Name 1
Information: TEST INTERNAL VALUE 1

===Record====
Name: Test Name 2
Information: TEST REFERENCE VALUE 2

===Record====
Name: Test Name 3
Information: TEST REFERENCE VALUE 3

使用键来引用您的信息或人员元素,您可以使用它们的 ID 来引用这些元素。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="text"/>
  
  <xsl:key name="infoKey" match="Information" use="@id"/>
  <xsl:key name="personKey" match="Person" use="@id"/>
  
  <xsl:template match="/">
    <xsl:text>Envelope Output</xsl:text>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="Envelope/Records/Record"/>
  </xsl:template>
  
  <xsl:template match="Record">
    <xsl:text>&#10;</xsl:text>
    <xsl:text>===Record===</xsl:text>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="Person"/>
    <xsl:apply-templates select="Information"/>
  </xsl:template>
  
  <xsl:template match="Information[Value]">
    <xsl:text>Information: </xsl:text><xsl:value-of select="Value"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  
  <xsl:template match="Information[not(Value)]">
    <xsl:text>Information: </xsl:text><xsl:value-of select="key('infoKey',@id)/Value"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  
  <xsl:template match="Person[name]">
    <xsl:text>Name: </xsl:text><xsl:value-of select="name"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  
  <xsl:template match="Person[not(name)]">
    <xsl:text>Information: </xsl:text><xsl:value-of select="key('personKey',@id)/name"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  
</xsl:stylesheet>

看到它在这里工作: https://xsltfiddle.liberty-development.net/6q1SDkc/1

更新了答案。 结合人员和信息模板。 我认为将它们分开会更清楚,而且维护起来也不难,但是如果您更喜欢这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="text"/>
  
  <xsl:key name="infoKey" match="Information" use="@id"/>
  <xsl:key name="personKey" match="Person" use="@id"/>
  
  <xsl:template match="/">
    <xsl:text>Envelope Output</xsl:text>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="Envelope/Records/Record"/>
  </xsl:template>
  
  <xsl:template match="Record">
    <xsl:text>&#10;</xsl:text>
    <xsl:text>===Record===</xsl:text>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="Person"/>
    <xsl:apply-templates select="Information"/>
  </xsl:template>
  
  <xsl:template match="Information">
    <xsl:text>Information: </xsl:text><xsl:value-of select="concat(Value,key('infoKey',@id)/Value)"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  
  <xsl:template match="Person">
    <xsl:text>Name: </xsl:text><xsl:value-of select="concat(name,key('personKey',@id)/name)"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  
</xsl:stylesheet>

看到它在这里工作: https://xsltfiddle.liberty-development.net/6q1SDkc/3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM