2013-04-05 80 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