1

1 つの .XML ファイルを取り込み、入力ファイルのサブセットである N 個のファイルを出力する必要があります。このサブセットは、2 つのノードの述語チェックに基づいています。私の計画は、入力ファイルを XSLT テンプレートで N 回実行して、各ファイルを出力することです。

私の入力は次のようになります。

<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:template-match に入れるように変更すると、それらのタグが複数回繰り返されます/

一致述語を /employee_data/employees[employee/agency_code='22' または employee/offices_administered/office_administered/@agency_code='22'] に変更すると、すべての従業員が取得されます。

マッチの出力全体を 2 つの親タグでラップする魔法が必要なようです。

4

1 に答える 1

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 を使用すると、変換を 1 回実行するだけで 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 ドキュメントに対してこの変換を実行すると、次の 2 つのファイルが作成されます。

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
于 2013-04-05T03:07:50.497 に答える