XSL转换问题

时间:2016-10-10 14:06:28

标签: xml xslt xml-parsing

我正在尝试将带有XSL的XML文件转换为另一种格式如下的XML:

输入文件:

<mediaRecords>
    <media mediaName="ID Generator_000005" mediaType="Video" origSOM="00:00:00:00" creationTime="2016-02-12T10:16:48" modifiedTime="2016-02-12T10:16:48">
        <properties>
            <classifications>
                <classification classification="MediaType" category="[Unknown]"/>
                <classification classification="MediaType2" category="[Unknown]"/>
                <classification classification="QA Status" category="[Unknown]"/>
            </classifications>
            <markups/>
        </properties>
        <mediaInstances>
            <mediaInstance mediaSetName="Ingest Device" version="1" versionHint="Initial" duration="00:00:00:00" position="00:00:00:00" directory="demoDevice/mediaDir" filename="ID Generator_000005" creationStartTime="2016-02-12T10:16:48:00" creationEndTime="2016-02-12T10:16:48:00" sourceURL="[Unknown]" destURL="[Unknown]">
                <properties/>
            </mediaInstance>
        </mediaInstances>
    </media>
</mediaRecords>

XLS:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
   <xsl:element name="Material">
      <xsl:apply-templates select="mediaRecords/media/properties/classifications"/>
   </xsl:element>
</xsl:template>
<xsl:template match="mediaRecords/media/properties/classifications">
   <xsl:element name="classification" >
      <xsl:attribute name="test">
         <xsl:value-of select="/mediaRecords/media/properties/classifications/classification/@classification" />
      </xsl:attribute>
   </xsl:element> 
   <xsl:element name="classification" >
      <xsl:attribute name="test2">
         <xsl:value-of select="/mediaRecords/media/properties/classifications/classification/@classification" />
      </xsl:attribute>
   </xsl:element>
   <xsl:element name="media" >
      <xsl:attribute name="MatID">
         <xsl:value-of select="/mediaRecords/media/@mediaName" />
      </xsl:attribute>
      </xsl:element>
      <xsl:element name="media" >
    <xsl:attribute name="startTime">
         <xsl:value-of select="/mediaRecords/media/@origSOM" />
    </xsl:attribute>
    </xsl:element>
    <xsl:element name="media" >
    <xsl:attribute name="type">
         <xsl:value-of select="/mediaRecords/media/@mediaType" />
    </xsl:attribute>
   </xsl:element>
   <xsl:element name="xxx" >
    <xsl:attribute name="marios">
         <xsl:value-of select="/mediaRecords/media/mediaInstances/mediaInstance/@mediaSetName" />
    </xsl:attribute>
   </xsl:element>
</xsl:template>
</xsl:stylesheet>

所需的XML输出:

<Material>
 <classification test="MediaType" />
 <classification test2="MediaType" />
 <media MatID="ID Generator_000005" />
 <media startTime="00:00:00:00" />
 <Track>
  <media type="Video" />
  <xxx marios="Ingest Device" />
 </Track>
</Material>
<Request>
<classification test="MediaType" />
<media type="Video" />
<xxx marios="Ingest Device" />
</Request>

在我的代码中,我有 2个问题。

首先,我无法将<Track><Request>嵌套为所需的输出。

第二个是在我的原始XML中,我有3次分类,我想要例如只输出第二个或第三个。我如何选择我能输出哪一个?

2 个答案:

答案 0 :(得分:0)

AFAICT,可以更简单地使用以下方式实现所需的输出:

XSLT 1.0

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

<xsl:template match="/mediaRecords">
    <Material>
        <classification test="{media/properties/classifications/classification[2]/@classification}" />
        <media MatID="{media/@mediaName}" />
        <media startTime="{media/@origSOM}" />
        <Track>
            <media type="{media/@mediaType}" />
            <xxx marios="{media/mediaInstances/mediaInstance/@mediaSetName}" />
        </Track>
    </Material>
    <Request>
        <classification test="MediaType" />
        <media type="{media/@mediaType}" />
        <xxx marios="{media/mediaInstances/mediaInstance/@mediaSetName}" />
    </Request>
</xsl:template>

</xsl:stylesheet>

这将选择第二个classification并返回:

<?xml version="1.0" encoding="UTF-8"?>
<Material>
   <classification test="MediaType2"/>
   <media MatID="ID Generator_000005"/>
   <media startTime="00:00:00:00"/>
   <Track>
      <media type="Video"/>
      <xxx marios="Ingest Device"/>
   </Track>
</Material>
<Request>
   <classification test="MediaType"/>
   <media type="Video"/>
   <xxx marios="Ingest Device"/>
</Request>

请注意,这假设输入中只有一个媒体记录。

另请注意,输出不是格式良好的XML,因为它没有单个根元素。

答案 1 :(得分:0)

您可以通过[n]从1开始选择第n个元素。

 <?xml version="1.0" encoding="iso-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
      <xsl:template match="/">
        <xsl:element name="Material">
          <xsl:apply-templates select="mediaRecords/media/properties/classifications"/>
        </xsl:element>
        <Request>
          <xsl:element name="classification" >
            <xsl:attribute name="test">
              <xsl:value-of select="/mediaRecords/media/properties/classifications/classification[1]/@classification" />
            </xsl:attribute>
          </xsl:element>
          <xsl:call-template name="mediaXXX" />
        </Request>
      </xsl:template>
      <xsl:template match="mediaRecords/media/properties/classifications">
        <xsl:element name="classification" >
          <xsl:attribute name="test">
            <xsl:value-of select="/mediaRecords/media/properties/classifications/classification[2]/@classification" />
          </xsl:attribute>
        </xsl:element>
        <xsl:element name="classification" >
          <xsl:attribute name="test2">
            <xsl:value-of select="/mediaRecords/media/properties/classifications/classification[3]/@classification" />
          </xsl:attribute>
        </xsl:element>
        <xsl:element name="media" >
          <xsl:attribute name="MatID">
            <xsl:value-of select="/mediaRecords/media/@mediaName" />
          </xsl:attribute>
        </xsl:element>
        <xsl:element name="media" >
          <xsl:attribute name="startTime">
            <xsl:value-of select="/mediaRecords/media/@origSOM" />
          </xsl:attribute>
        </xsl:element>
        <Track>
          <xsl:call-template name="mediaXXX" />
        </Track>
      </xsl:template>
      <xsl:template name="mediaXXX">
        <xsl:element name="media" >
          <xsl:attribute name="type">
            <xsl:value-of select="/mediaRecords/media/@mediaType" />
          </xsl:attribute>
        </xsl:element>
        <xsl:element name="xxx" >
          <xsl:attribute name="marios">
            <xsl:value-of select="/mediaRecords/media/mediaInstances/mediaInstance/@mediaSetName" />
          </xsl:attribute>
        </xsl:element>
      </xsl:template>
    </xsl:stylesheet>