2017-04-03 71 views
0

我在寻找帮助。我有一个带有下拉的XFA表单(基于XML),它保存每个项目的显示和保存值。由于列表可能非常长,我试图使用XSLT 1.0进行过滤。如何使用XSLT 1.0一次过滤两个xml树?

源XML DROM下拉可能是这样的:

<?xml version="1.0" encoding="UTF-8"?> 
<field name="DropDownList" xmlns="http://www.xfa.org/schema/xfa-form/2.8/"> 
    <!-- Displayed items to be filtered --> 
    <items xmlns="http://www.xfa.org/schema/xfa-template/3.6/"> 
     <text>Lorem Ipsum 0030</text> 
     <text>Lorem Ipsum 0060</text> 
     <text>Lorem Ipsum 0070</text> 
     <text>Lorem Ipsum 0080</text> 
     <text>Lorem Ipsum 0100</text> 
     <text>Lorem Ipsum 0110</text> 
     <text>Lorem Ipsum 0120</text> 
     <text>Lorem Ipsum 0130</text> 
     <text>Lorem Ipsum 0140</text> 
    </items> 
    <!-- Hidden save items to be filtered too --> 
    <items save="1" presence="hidden" xmlns="http://www.xfa.org/schema/xfa-template/3.6/"> 
     <text>item0</text> 
     <text>item1</text> 
     <text>item2</text> 
     <text>item3</text> 
     <text>item4</text> 
     <text>item5</text> 
     <text>item6</text> 
     <text>item7</text> 
     <text>item8</text> 
     <text>item9</text> 
    </items> 
</field> 

我现在的样式看起来是这样的:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xfa="http://www.xfa.org/schema/xfa-form/2.8/" xml:space="preserve"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no" standalone="yes"/> 
    <xsl:template match="/"> 
     <field name="DropDownList"> 
      <xsl:apply-templates/> 
     </field> 
    </xsl:template> 
    <xsl:template match="/*[local-name()='field']/*[local-name()='items']" > 
     <items xmlns="http://www.xfa.org/schema/xfa-template/3.6/"> 
      <xsl:for-each select="./*[local-name()='text']"> 
       <xsl:if test="contains(., '01')"> 
        <text> 
         <xsl:value-of select="."/> 
        </text> 
       </xsl:if> 
      </xsl:for-each> 
     </items> 
    </xsl:template> 
</xsl:stylesheet> 

我需要的是像以前一样载入它相同的XML结构到下拉列表中,但我还没有找到一种方式来获得第二个项目树填充正确的数据。我正在考虑使用参数或变量来保存第一个项目树中节点的索引,并在第二个项目树中找到相关节点,但是怎么做?

<?xml version="1.0" encoding="UTF-8"?> 
<field name="DropDownList" xmlns="http://www.xfa.org/schema/xfa-form/2.8/"> 
    <items xmlns="http://www.xfa.org/schema/xfa-template/3.6/"> 
     <text>Lorem Ipsum 0100</text> 
     <text>Lorem Ipsum 0110</text> 
     <text>Lorem Ipsum 0120</text> 
     <text>Lorem Ipsum 0130</text> 
     <text>Lorem Ipsum 0140</text> 
    </items> 
    <items save="1" presence="hidden" xmlns="http://www.xfa.org/schema/xfa-template/3.6/"> 
     <text>item5</text> 
     <text>item6</text> 
     <text>item7</text> 
     <text>item8</text> 
     <text>item9</text> 
    </items> 
</field> 

回答

1

一个简单的方法是在模板和应用模板上使用模式。所以,将模式属性添加到apply-templates。然后,将具有相同名称的模式属性添加到您使用应用模板定位的模板。然后对于第二个输出,或者使用不同的模式,或者让它在没有模式的情况下流过。

0

感谢您的输入。我做了另一个样式表,它正在做我正在寻找的东西。但是,我不认为这个解决方案是理想的,因为我要检查所有节点的第一项树下两次......

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xfa="http://www.xfa.org/schema/xfa-form/2.8/" xml:space="preserve"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" standalone="yes"/> 
    <xsl:variable name="filterText" select="01"/> 
    <!--Filter display items--> 
    <xsl:template match="//*[local-name()='items'][1]/*[local-name()='text']" mode="filterDisplayItems"> 
     <xsl:if test="contains(., $filterText)"> 
      <xsl:copy-of select="."/> 
     </xsl:if> 
    </xsl:template> 
    <!--Filter save items--> 
    <xsl:template match="//*[local-name()='items'][1]/*[local-name()='text']" mode="filterSaveItems"> 
     <xsl:param name="nodeIndex" select="position()"/> 
     <xsl:if test="contains(., $filterText)"> 
      <xsl:copy-of select="//*[local-name()='items'][2]/*[local-name()='text'][$nodeIndex]"/> 
     </xsl:if> 
    </xsl:template> 
    <xsl:template match="/"> 
     <field name="ListBackup"> 
      <!--Create filtered list of display items--> 
      <items xmlns="http://www.xfa.org/schema/xfa-template/3.6/"> 
       <xsl:apply-templates select="//*[local-name()='items'][1]/*[local-name()='text']" mode="filterDisplayItems"/> 
      </items> 
      <!--Create filtered list of save items--> 
      <items save="1" presence="hidden" xmlns="http://www.xfa.org/schema/xfa-template/3.6/"> 
       <xsl:apply-templates select="//*[local-name()='items'][1]/*[local-name()='text']" mode="filterSaveItems"/> 
      </items> 
     </field> 
    </xsl:template> 
</xsl:stylesheet> 

...这引起我的眼睛表现滞后。一定会有更好的办法。当筛选第一个项目树的模板找到匹配项时,您可以很容易地得到它的索引... select =“position()”。这应该传递给过滤第二项目树的模板。在那里,你只需要通过索引来复制节点。任何想法如何实现这一目标?