2013-04-05 56 views
1

我需要输入1个.XML文件,并输出N个输入文件的子集文件。该子集基于2个节点的谓词检查。我的计划是通过XSLT模板运行输入文件N次以输出每个文件。XSLT - 在标签中输出xsl:模板输出

我的输入是这样的:

<employee_data> 
<employees> 
    <employee id="1"> 
    <first_name>2sk8d</first_name>  
    <agency_code>38</agency_code> 
    <offices_administered> 
     <office_administered office_identifier="ALLPOIs" agency_code="HL" /> 
    </offices_administered> 
    </employee> 
    <employee id="2"> 
     <first_name>2sk8d</first_name> 
     <agency_code>24</agency_code> 
     <offices_administered> 
      <office_administered office_identifier="ALLPOIs" agency_code="22" /> 
     </offices_administered> 
    </employee> 
    <employee id="3"> 
     <first_name>2sk8d</first_name> 
     <agency_code>22</agency_code> 
     <offices_administered> 
      <office_administered office_identifier="ALLPOIs" agency_code="HL" /> 
     </offices_administered> 
    </employee>  
</employees> 

我的XSLT看起来像这样

<?xml version="1.0" encoding="utf-8"?> 

<xsl:output method="xml" indent="yes" encoding="utf-16"/>     

<xsl:template match="/employee_data/employees/employee[agency_code='22' or offices_administered/office_administered/@agency_code='22']">   
    <xsl:copy> 
     <xsl:copy-of select="."/> 
     <xsl:apply-templates/> 
    </xsl:copy>   
</xsl:template> 

<xsl:template match="@* | node()"> 
    <xsl:message terminate="no"> 
     Catch 1 <xsl:value-of select="name()"/> 
    </xsl:message> 
</xsl:template> 

我的问题是我的输出不包含EmployeeData或Employees根/父节点。

如果我改变我的XSLT把第一的xsl:模板匹配,那么这些标签被重复多次/

如果我改变我的比赛谓词/ employee_data /雇员[雇员/ agency_code = '22 '或员工/ offices_administered/office_administered/@ agency_code = '22']然后我得到所有员工。

这几乎就像我想要一些神奇的东西在我的两个父标记中包裹我匹配的整个输出。

回答

0

从我从这个问题明白了,你想是这样的:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/"> 
    <employee_data> 
     <employees> 

      <xsl:apply-templates select= 
      "/*/employees/employee 
       [agency_code='22' 
       or offices_administered/office_administered/@agency_code='22']"/> 
     </employees> 
    </employee_data> 
</xsl:template> 

    <xsl:template match="employee"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 

    <xsl:template match="@* | node()"> 
    <xsl:message terminate="no"> 
     Catch 1 <xsl:value-of select="name()"/> 
    </xsl:message> 
    </xsl:template> 
</xsl:stylesheet> 

当这种变换所提供的XML文档应用:

<employee_data> 
    <employees> 
     <employee id="1"> 
      <first_name>2sk8d</first_name> 
      <agency_code>38</agency_code> 
      <offices_administered> 
       <office_administered office_identifier="ALLPOIs" agency_code="HL" /> 
      </offices_administered> 
     </employee> 
     <employee id="2"> 
      <first_name>2sk8d</first_name> 
      <agency_code>24</agency_code> 
      <offices_administered> 
       <office_administered office_identifier="ALLPOIs" agency_code="22" /> 
      </offices_administered> 
     </employee> 
     <employee id="3"> 
      <first_name>2sk8d</first_name> 
      <agency_code>22</agency_code> 
      <offices_administered> 
       <office_administered office_identifier="ALLPOIs" agency_code="HL" /> 
      </offices_administered> 
     </employee> 
    </employees> 
</employee_data> 

通缉,会产生正确的结果

<employee_data> 
    <employees> 
     <employee id="2"> 
     <first_name>2sk8d</first_name> 
     <agency_code>24</agency_code> 
     <offices_administered> 
      <office_administered office_identifier="ALLPOIs" agency_code="22"/> 
     </offices_administered> 
     </employee> 
     <employee id="3"> 
     <first_name>2sk8d</first_name> 
     <agency_code>22</agency_code> 
     <offices_administered> 
      <office_administered office_identifier="ALLPOIs" agency_code="HL"/> 
     </offices_administered> 
     </employee> 
    </employees> 
</employee_data> 

二, XSLT 2.0溶液

使用XSLT 2.0,能够与所述变换的单次运行创建所有N个文档:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pCodes" as="xs:string+" select="'22', '38'"/> 
<xsl:variable name="vDoc" select="/"/> 

<xsl:template match="/"> 
    <xsl:for-each select="$pCodes"> 
    <xsl:variable name="vCode" select="."/> 
    <xsl:result-document href="'Agency'{.}.xml"> 
     <employee_data> 
      <employees> 

       <xsl:apply-templates select= 
       "$vDoc/*/employees/employee 
        [agency_code=$vCode 
        or offices_administered/office_administered 
               /@agency_code=$vCode]"/> 
      </employees> 
     </employee_data> 
     </xsl:result-document> 
    </xsl:for-each> 
</xsl:template> 

    <xsl:template match="employee"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 

    <xsl:template match="@* | node()"> 
    <xsl:message terminate="no"> 
     Catch 1 <xsl:value-of select="name()"/> 
    </xsl:message> 
    </xsl:template> 
</xsl:stylesheet> 

当运行在相同的提供(上图)XML这种转化文件,创建两个文件:

Saxon 9.1.0.5J from Saxonica 
Java version 1.6.0_31 
Stylesheet compilation time: 610 milliseconds 
Processing file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml 
Building tree for file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml using class net.sf.saxon.tinytree.TinyBuilder 
Tree built in 0 milliseconds 
Tree size: 25 nodes, 21 characters, 9 attributes 
Loading net.sf.saxon.event.MessageEmitter 

Writing to file:/C:/Program%20Files/Java/jre6/bin/'Agency'22.xml 
Writing to file:/C:/Program%20Files/Java/jre6/bin/'Agency'38.xml 

Execution time: 94 milliseconds 
Memory used: 11464160 
NamePool contents: 26 entries in 26 chains. 6 prefixes, 7 URIs 
+0

完美,非常感谢你@! – Dave 2013-04-05 03:16:52

+1

@Dave,不客气。我更新了解决方案,简化了它。 – 2013-04-05 03:18:06

+1

@Dave,另请参见上次更新:如果您有可用的XSLT 2.0处理器,则只需执行一次转换即可创建所有N个文件。 – 2013-04-05 03:24:02