2013-04-05 4 views
1

Мне нужно взять файл .XML и вывести N файлов, которые являются подмножеством входного файла. Этот поднабор основан на проверке предикатов на 2 узла. Мой план состоит в том, чтобы запустить входной файл по шаблону XSLT N раз для вывода каждого файла.XSLT - wrapping 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 'или employee/office_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> 

II. 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

+1

@ Дэйв, добро пожаловать. Я обновил решение, упростив его. –

+1

@Dave, см. Также последнее обновление: если у вас есть процессор XSLT 2.0, вы можете создать все N файлов с одним выполнением преобразования. –