XSLT 将元素转换为属性并删除元素 XML

XSLT transform an element to an attribute and remove an element XML

我之前问过类似的问题,但我在这里有点困惑。

我有一个 XML,我想将一些元素转换为其父元素的属性。我已经为一个元素这样做了,但我想为另一个元素这样做。我认为这将是复制 XSLT 代码并重命名需要更改的部分的情况,但它并没有按预期工作 - 它从元素中删除了节点,但没有将它们更改为属性,它们是只是消失了。

我还尝试根据与另一个元素相比的值来删除元素。这也是在我的 XSLT 中的另一个元素中完成的,但是当我复制代码时,我似乎无法获得相同的结果。当 "task_info" 中的 "task_seq_id" 与 "press_section" 中的 "sequence_id" 不匹配时,我想删除嵌套在 "press_section" 中的 "task_info" 元素。

最后,我还注意到我的 XSLT 不再从我的 XML 中删除 "dataroot" 元素。

老实说,我真的看不懂我在这里做什么,所以我很感激一些帮助。

谢谢大家!

这是我的输入 XML;

<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2015-01-16T10:32:47">
<order>
<ORDERPK>4</ORDERPK>
<job_id>S019191-1</job_id>
<site_code>DG</site_code>
<Replace>true</Replace>
<job_description>TEST</job_description>
<order_qty>2000</order_qty>
<depth>10</depth>
<width>8</width>
<cover_pagination>4</cover_pagination>
<text_pagination>12</text_pagination>
<delivery_commence_date>15/1/2014</delivery_commence_date>
<job_site>DG</job_site>
<managing_printer>DG</managing_printer>
<is_managing_printer>True</is_managing_printer>
</order>
<master_version>
<ORDER>3</ORDER>
<version_code>COMM</version_code>
<version_common>true</version_common>
<version_finished>false</version_finished>
<version_description>common</version_description>
<version_nett_qty>20000</version_nett_qty>
<version_special_qty>0</version_special_qty>
</master_version>
<master_version>
<ORDER>4</ORDER>
<version_code>COMM</version_code>
<version_common>true</version_common>
<version_finished>false</version_finished>
<version_description>common</version_description>
<version_nett_qty>2000</version_nett_qty>
</master_version>
<press_section>
<ORDER>3</ORDER>
<signature_id>001</signature_id>
<sequence_id>0</sequence_id>
<sequence_alpha>A</sequence_alpha>
<description>4pp Cover</description>
<pagination>4</pagination>
<trim_size>10 x 8</trim_size>
</press_section>
<press_section>
<ORDER>4</ORDER>
<signature_id>001</signature_id>
<sequence_id>0</sequence_id>
<sequence_alpha>A</sequence_alpha>
<description>4pp Cover</description>
<pagination>4</pagination>
<trim_size>10 x 8</trim_size>
</press_section>
<press_section>
<ORDER>4</ORDER>
<signature_id>001</signature_id>
<sequence_id>1</sequence_id>
<sequence_alpha>A</sequence_alpha>
<description>6pp Cover</description>
<pagination>6</pagination>
<trim_size>10 x8</trim_size>
</press_section>
<version>
<ORDER>3</ORDER>
<version_code>COMM</version_code>
</version>
<version>
<ORDER>4</ORDER>
<version_code>COMM</version_code>
</version>
<task_info_press_section>
<ORDER>3</ORDER>
<PRESS_x0020_SECTION>3</PRESS_x0020_SECTION>
<confirmed>true</confirmed>
<maintenance>false</maintenance>
<provisional>false</provisional>
<task_sub_job_id>S026500-1-001COMM</task_sub_job_id>
<task_seq_id>0</task_seq_id>
<task_description>4ppCover</task_description>
<task_qty_rqd>20000</task_qty_rqd>
<task_resource_id>2</task_resource_id>
</task_info_press_section>
<task_info_press_section>
<ORDER>4</ORDER>
<PRESS_x0020_SECTION>4</PRESS_x0020_SECTION>
<confirmed>-1</confirmed>
<maintenance>0</maintenance>
<provisional>0</provisional>
<task_sub_job_id>S019191-1-001COMM</task_sub_job_id>
<task_seq_id>0</task_seq_id>
<task_description>4pp Cover</task_description>
<task_qty_rqd>1500</task_qty_rqd>
<task_resource_id>1</task_resource_id>
</task_info_press_section>
<task_info_press_section>
<ORDER>4</ORDER>
<PRESS_x0020_SECTION>4</PRESS_x0020_SECTION>
<confirmed>-1</confirmed>
<maintenance>0</maintenance>
<provisional>0</provisional>
<task_sub_job_id>S019191-1-001COMM</task_sub_job_id>
<task_seq_id>1</task_seq_id>
<task_description>6pp Cover</task_description>
<task_qty_rqd>500</task_qty_rqd>
<task_resource_id>1</task_resource_id>
</task_info_press_section>
</dataroot>

这是 XSLT 1;

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">


   <xsl:template match="/">
     <orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tg="http://www.technique-group.com" xsi:schemaLocation="http://www.technique-group.com/schemas TGScheduleImport_v1.4.xsd" tg:version="1.2">
       <xsl:apply-templates/>
     </orders>
   </xsl:template>

   <!-- remove elements that don't match order -->
   <xsl:template match="master_version[not(ORDER = //order/ORDERPK)]"/>
   <xsl:template match="press_section[not(ORDER = //order/ORDERPK)]"/>
   <xsl:template match="version[not(ORDER = //order/ORDERPK)]"/>
   <xsl:template match="task_info_press_section[not(ORDER = //order/ORDERPK)]"/>
   <xsl:template match="task_info_post_press[not(ORDER = //order/ORDERPK)]"/>
   <xsl:template match="post_press_version[not(ORDER = //order/ORDERPK)]"/>

   <!-- removed unwanted nodes from all elements -->
   <xsl:template match="ORDER"/>
   <xsl:template match="ORDERPK"/>
   <xsl:template match="PRESS_x0020_SECTION"/>
   <xsl:template match="POST_x0020_PRESS"/>


   <xsl:strip-space elements="*"/>
   <xsl:output method="xml" indent="yes"/>


   <!-- create attributes in order element -->
   <xsl:template match="dataroot">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()[not(self::*)]|order"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="job_id | site_code | replace | Replace"/>

   <xsl:template match="order">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()[not(self::*)]|task_info_press_section"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="confirmed | maintenance | provisional"/>


   <!-- identity transform -->
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>


   <!-- nest specified element within matched element -->
   <xsl:template match="press_section">
    <press_section>
       <xsl:apply-templates select="node()"/>
       <xsl:apply-templates select="../version"/>
    </press_section>
   </xsl:template>

   <xsl:template match="version">
    <version>
       <xsl:apply-templates select="node()"/>
       <xsl:apply-templates select="../task_info_press_section"/>
    </version>
   </xsl:template>

   <xsl:template match="post_press_version">
    <post_press_version>
       <xsl:apply-templates select="node()"/>
       <xsl:apply-templates select="../task_info_post_press"/>
    </post_press_version>
   </xsl:template>

   <xsl:template match="task_info_press_section">
    <task_info_press_section confirmed="{confirmed}" maintenance="{maintenance}" provisional="{provisional}">
       <xsl:apply-templates select="node()"/>
       <xsl:apply-templates select="../*[not(self::task_info_press_section)]"/>
    </task_info_press_section>
   </xsl:template>


   <!-- nest all elements within order and create attributes -->
   <xsl:template match="order">
    <order job_id="{job_id}" site_code="{site_code}" replace="{Replace}">
       <xsl:apply-templates select="node()"/>
       <xsl:apply-templates select="../*[not(self::order) and not(self::version) and not(self::task_info_press_section) and not(self::task_info_post_press)]"/>
    </order>
   </xsl:template>


   <!-- rename elements to specified name -->
   <xsl:template match="task_info_press_section">
      <xsl:element name="task_info">
         <xsl:apply-templates/>
      </xsl:element>
   </xsl:template>

   <xsl:template match="task_info_post_press">
      <xsl:element name="task_info">
         <xsl:apply-templates/>
      </xsl:element>
   </xsl:template>

</xsl:stylesheet>

这是 XSLT 2;

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:tg="http://www.technique-group.com"
    version="1.2">

<xsl:template match="*">
  <xsl:element name="tg:{local-name()}" namespace="http://www.technique-group.com">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

这是我的输出 XML;

<?xml version="1.0" encoding="UTF-8"?>
<tg:orders xmlns:tg="http://www.technique-group.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.technique-group.com/schemas TGScheduleImport_v1.4.xsd" tg:version="1.2">
   <tg:dataroot generated="2015-01-16T10:32:47">
      <tg:order job_id="S019191-1" site_code="DG" replace="true">
         <tg:job_description>TEST</tg:job_description>
         <tg:order_qty>2000</tg:order_qty>
         <tg:depth>10</tg:depth>
         <tg:width>8</tg:width>
         <tg:cover_pagination>4</tg:cover_pagination>
         <tg:text_pagination>12</tg:text_pagination>
         <tg:delivery_commence_date>15/1/2014</tg:delivery_commence_date>
         <tg:job_site>DG</tg:job_site>
         <tg:managing_printer>DG</tg:managing_printer>
         <tg:is_managing_printer>True</tg:is_managing_printer>
         <tg:master_version>
            <tg:version_code>COMM</tg:version_code>
            <tg:version_common>true</tg:version_common>
            <tg:version_finished>false</tg:version_finished>
            <tg:version_description>common</tg:version_description>
            <tg:version_nett_qty>2000</tg:version_nett_qty>
         </tg:master_version>
         <tg:press_section>
            <tg:signature_id>001</tg:signature_id>
            <tg:sequence_id>0</tg:sequence_id>
            <tg:sequence_alpha>A</tg:sequence_alpha>
            <tg:description>4pp Cover</tg:description>
            <tg:pagination>4</tg:pagination>
            <tg:trim_size>10 x 8</tg:trim_size>
            <tg:version>
               <tg:version_code>COMM</tg:version_code>
               <tg:task_info>
                  <tg:task_sub_job_id>S019191-1-001COMM</tg:task_sub_job_id>
                  <tg:task_seq_id>0</tg:task_seq_id>
                  <tg:task_description>4pp Cover</tg:task_description>
                  <tg:task_qty_rqd>1500</tg:task_qty_rqd>
                  <tg:task_resource_id>1</tg:task_resource_id>
               </tg:task_info>
               <tg:task_info>
                  <tg:task_sub_job_id>S019191-1-001COMM</tg:task_sub_job_id>
                  <tg:task_seq_id>1</tg:task_seq_id>
                  <tg:task_description>6pp Cover</tg:task_description>
                  <tg:task_qty_rqd>500</tg:task_qty_rqd>
                  <tg:task_resource_id>1</tg:task_resource_id>
               </tg:task_info>
            </tg:version>
         </tg:press_section>
         <tg:press_section>
            <tg:signature_id>001</tg:signature_id>
            <tg:sequence_id>1</tg:sequence_id>
            <tg:sequence_alpha>A</tg:sequence_alpha>
            <tg:description>6pp Cover</tg:description>
            <tg:pagination>6</tg:pagination>
            <tg:trim_size>10 x8</tg:trim_size>
            <tg:version>
               <tg:version_code>COMM</tg:version_code>
               <tg:task_info>
                  <tg:task_sub_job_id>S019191-1-001COMM</tg:task_sub_job_id>
                  <tg:task_seq_id>0</tg:task_seq_id>
                  <tg:task_description>4pp Cover</tg:task_description>
                  <tg:task_qty_rqd>1500</tg:task_qty_rqd>
                  <tg:task_resource_id>1</tg:task_resource_id>
               </tg:task_info>
               <tg:task_info>
                  <tg:task_sub_job_id>S019191-1-001COMM</tg:task_sub_job_id>
                  <tg:task_seq_id>1</tg:task_seq_id>
                  <tg:task_description>6pp Cover</tg:task_description>
                  <tg:task_qty_rqd>500</tg:task_qty_rqd>
                  <tg:task_resource_id>1</tg:task_resource_id>
               </tg:task_info>
            </tg:version>
         </tg:press_section>
      </tg:order>
   </tg:dataroot>
</tg:orders>

这是我想要的输出;

<?xml version="1.0" encoding="UTF-8"?>
<tg:orders xmlns:tg="http://www.technique-group.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.technique-group.com/schemas TGScheduleImport_v1.4.xsd" tg:version="1.2">
      <tg:order job_id="S019191-1" site_code="DG" replace="true">
         <tg:job_description>TEST</tg:job_description>
         <tg:order_qty>2000</tg:order_qty>
         <tg:depth>10</tg:depth>
         <tg:width>8</tg:width>
         <tg:cover_pagination>4</tg:cover_pagination>
         <tg:text_pagination>12</tg:text_pagination>
         <tg:delivery_commence_date>15/1/2014</tg:delivery_commence_date>
         <tg:job_site>DG</tg:job_site>
         <tg:managing_printer>DG</tg:managing_printer>
         <tg:is_managing_printer>True</tg:is_managing_printer>
         <tg:master_version>
            <tg:version_code>COMM</tg:version_code>
            <tg:version_common>true</tg:version_common>
            <tg:version_finished>false</tg:version_finished>
            <tg:version_description>common</tg:version_description>
            <tg:version_nett_qty>2000</tg:version_nett_qty>
         </tg:master_version>
         <tg:press_section>
            <tg:signature_id>001</tg:signature_id>
            <tg:sequence_id>0</tg:sequence_id>
            <tg:sequence_alpha>A</tg:sequence_alpha>
            <tg:description>4pp Cover</tg:description>
            <tg:pagination>4</tg:pagination>
            <tg:trim_size>10 x 8</tg:trim_size>
            <tg:version>
               <tg:version_code>COMM</tg:version_code>
               <tg:task_info confirmed="true" maintenance="false" provisional="false">
                  <tg:task_sub_job_id>S019191-1-001COMM</tg:task_sub_job_id>
                  <tg:task_seq_id>0</tg:task_seq_id>
                  <tg:task_description>4pp Cover</tg:task_description>
                  <tg:task_qty_rqd>1500</tg:task_qty_rqd>
                  <tg:task_resource_id>1</tg:task_resource_id>
               </tg:task_info>
            </tg:version>
         </tg:press_section>
         <tg:press_section>
            <tg:signature_id>001</tg:signature_id>
            <tg:sequence_id>1</tg:sequence_id>
            <tg:sequence_alpha>A</tg:sequence_alpha>
            <tg:description>6pp Cover</tg:description>
            <tg:pagination>6</tg:pagination>
            <tg:trim_size>10 x8</tg:trim_size>
            <tg:version>
               <tg:version_code>COMM</tg:version_code>
               <tg:task_info confirmed="true" maintenance="false" provisional="false">
                  <tg:task_sub_job_id>S019191-1-001COMM</tg:task_sub_job_id>
                  <tg:task_seq_id>1</tg:task_seq_id>
                  <tg:task_description>6pp Cover</tg:task_description>
                  <tg:task_qty_rqd>500</tg:task_qty_rqd>
                  <tg:task_resource_id>1</tg:task_resource_id>
               </tg:task_info>
            </tg:version>
         </tg:press_section>
      </tg:order>
</tg:orders>

要提出的第一点,你需要记住这一点,让两个模板匹配同一个元素,但没有对它们附加某种额外条件,这是错误的。您有两个匹配 order 的模板和两个匹配 task_info_press_section 的模板。每个应该只有一个。

着眼于你想要实现的目标,而不是你试图实现它的方式,我认为你真的应该采取不同的方法。您正在尝试向 order 元素添加子元素,并且您通过 selecting 所有模板来实现此目的,但模板例外排除与订单号不匹配的模板。

您可以采用的另一种方法是根据顺序显式 select 您要复制的子元素。你可以用钥匙很容易地做到这一点...

<xsl:key name="master_version" match="master_version" use="ORDER" />
<xsl:key name="press_section" match="press_section" use="ORDER" />
<xsl:key name="version" match="version" use="ORDER" />
<xsl:key name="task_info_press_section" match="task_info_press_section" use="ORDER" />

因此,对于匹配 "order" 的模板,您可以像这样明确设置嵌套的 "master_version" 和 "press_section"

<xsl:template match="order">
   <order job_id="{job_id}" site_code="{site_code}" replace="{Replace}">
      <xsl:apply-templates select="@*|node()" />
      <xsl:apply-templates select="key('master_version', ORDERPK)"/>
      <xsl:apply-templates select="key('press_section', ORDERPK)"/>
   </order>
</xsl:template>

对于 task_info_press_sectionpress_section 中的嵌套,我会将其与匹配 version 的模板结合起来。然后,您可以更轻松地向 selected task_info_press_section.

的键添加额外条件
<xsl:template match="press_section">
  <press_section>
   <xsl:apply-templates select="node()"/>
   <version>
        <xsl:apply-templates select="key('version', ORDER)/node()"/>
        <xsl:apply-templates select="key('task_info_press_section', ORDER)[task_seq_id = current()/sequence_id]"/>
   </version>
  </press_section>
</xsl:template>

所以current()在这种情况下,指的是当前press_section

试试这个大大简化的 XSLT

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

   <xsl:key name="master_version" match="master_version" use="ORDER" />
   <xsl:key name="press_section" match="press_section" use="ORDER" />
   <xsl:key name="version" match="version" use="ORDER" />
   <xsl:key name="task_info_press_section" match="task_info_press_section" use="ORDER" />

   <xsl:template match="ORDER"/>
   <xsl:template match="ORDERPK"/>
   <xsl:template match="PRESS_x0020_SECTION"/>
   <xsl:template match="job_id | site_code | replace | Replace"/>
   <xsl:template match="confirmed | maintenance | provisional"/>

   <!-- identity transform -->
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>


       <xsl:template match="dataroot">
     <orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:od="urn:schemas-microsoft-com:officedata" xmlns:tg="http://www.technique-group.com" xsi:schemaLocation="http://www.technique-group.com/schemas TGScheduleImport_v1.4.xsd" tg:version="1.2">
       <xsl:apply-templates select="order"/>
     </orders>
   </xsl:template>
   <xsl:template match="order">
      <order job_id="{job_id}" site_code="{site_code}" replace="{Replace}">
         <xsl:apply-templates select="@*|node()" />
         <xsl:apply-templates select="key('master_version', ORDERPK)"/>
         <xsl:apply-templates select="key('press_section', ORDERPK)"/>
      </order>
   </xsl:template>

   <xsl:template match="press_section">
    <press_section>
       <xsl:apply-templates select="node()"/>
       <version>
            <xsl:apply-templates select="key('version', ORDER)/node()"/>
            <xsl:apply-templates select="key('task_info_press_section', ORDER)[task_seq_id = current()/sequence_id]"/>
       </version>
    </press_section>
   </xsl:template>

   <xsl:template match="task_info_press_section">
    <task_info confirmed="{confirmed}" maintenance="{maintenance}" provisional="{provisional}">
       <xsl:apply-templates select="node()"/>
    </task_info>
   </xsl:template>

请注意,在回答您关于为什么 dataroot 未被删除的问题时,这是因为您明确地将其复制到输出

<xsl:template match="dataroot">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()[not(self::*)]|order"/>
   </xsl:copy>
</xsl:template>

在新样式sheet中,我有效地将匹配\dataroot的模板合二为一,所以dataroot有效地重命名为orders

   <xsl:template match="dataroot">
     <orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:od="urn:schemas-microsoft-com:officedata" xmlns:tg="http://www.technique-group.com" xsi:schemaLocation="http://www.technique-group.com/schemas TGScheduleImport_v1.4.xsd" tg:version="1.2">
       <xsl:apply-templates select="order"/>
     </orders>
   </xsl:template>