使用 MSXML 和标记之间的空格的 XSL 转换
XSL transformation with MSXML and whitespace between tags
我正在进行非常标准的 XSLT 转换。使用 MSXML(在 Oxygen XML 编辑器中)时,我得到以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<ProgramSchedules mediaCompanyID="00001" date="2017-06-08" channel="00019">
<Schedules>
<Schedule contentId="T17ADiamond008P2AA" startTime="06:29:56" endTime="06:30:11" rerun="true" eventType="AP">
</Schedule>
<Schedule contentId="T17AOslo-Sk236s1AA" startTime="06:30:11" endTime="06:30:31" rerun="true" eventType="AP">
</Schedule>
MSXML 4 和 Saxon 显示以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<ProgramSchedules mediaCompanyID="00001" date="2017-06-08" channel="00019">
<Schedules>
<Schedule contentId="T17ADiamond008P2AA" startTime="06:29:56" endTime="06:30:11" rerun="true" eventType="AP"></Schedule>
<Schedule contentId="T17AOslo-Sk236s1AA" startTime="06:30:11" endTime="06:30:31" rerun="true" eventType="AP"></Schedule>
这里的问题是我的 XML 模式没有验证第一个输出,因为 CRLF 出现在开始标记之后。
有没有办法在不更换处理器的情况下解决这个问题?
这是我的样式表的样子:
<?xml version='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:template match="/">
<ProgramSchedules>
<xsl:attribute name="mediaCompanyID">
<xsl:text>00001</xsl:text>
</xsl:attribute>
<xsl:attribute name="date">
<xsl:apply-templates select="txevents/search-criteria/dateselection/ES_DATESELECTION/firstvalue/ESP_DATE"/>
</xsl:attribute>
<xsl:attribute name="channel">
<xsl:choose>
<xsl:when test="starts-with(txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name, 'NRK1')">
<xsl:text>00019</xsl:text>
</xsl:when>
<xsl:when test="txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name = 'NRK2'">
<xsl:text>00029</xsl:text>
</xsl:when>
<xsl:when
test="txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name = 'NRK3' or txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name = 'SUPER'">
<xsl:text>00039</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>0</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<Schedules>
<xsl:for-each select="txevents/ES_BMTXEVENT">
<Schedule>
<xsl:attribute name="contentId">
<xsl:value-of select="translate(@productcode, '/', '')"/>
<xsl:value-of select="substring(transmission/ES_TRANSMISSION/@productVersionAsString, 2, 4)"/>
</xsl:attribute>
<xsl:attribute name="startTime">
<xsl:apply-templates select="starttime/ESP_TIMEDURATION"/>
</xsl:attribute>
<xsl:attribute name="endTime">
<xsl:apply-templates select="endtime/ESP_TIMEDURATION"/>
</xsl:attribute>
<xsl:attribute name="rerun">
<xsl:choose>
<xsl:when
test="(transmission/ES_TRANSMISSION/@tx_isrepeat = 'true') or (transmission/ES_TRANSMISSION/@tx_isrerun = 'true')">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="eventType">
<xsl:choose>
<xsl:when
test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Segment of program'">
<xsl:text>RP</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Trailer'">
<xsl:text>AP</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Sting/Vignett'">
<xsl:text>RP</xsl:text>
</xsl:when>
<xsl:when
test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Klokke NRK1 m/ tekst'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Klokke NRK Super'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Klokke NRK2'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Plakater 3'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'A1 fl on'">
<xsl:text>AP</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Sponsor'">
<xsl:text>BR</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'TTV-rulle NRK1'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'TTV-rulle NRK2'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>US</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute></Schedule>
</xsl:for-each>
</Schedules>
</ProgramSchedules>
</xsl:template>
<xsl:template match="ESP_TIMEDURATION">
<xsl:value-of select="format-number(@hours, '00')"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="format-number(@minutes, '00')"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="format-number(@seconds, '00')"/>
</xsl:template>
<xsl:template match="ESP_DATE">
<xsl:value-of select="@year"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@month, '00')"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@day, '00')"/>
</xsl:template>
<xsl:template match="ESP_TIMEINSTANT">
<xsl:value-of select="@year"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@month, '00')"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@day, '00')"/>
</xsl:template>
</xsl:stylesheet>
原始 XML 数据在这里:https://pastebin.com/RWGEi59c
在 Oxygen XML v17.1 中进行的一些实验表明,对 XSL 进行简单的更改就可以摆脱烦人的换行符。
在您的 XSL 代码的第 31 行,您有一条插入 <Schedule>
元素的指令,后跟一个换行符和第 32 行:
<Schedule>
<xsl:attribute name="contentId">
删除第 31 行末尾的换行符,这样第 31 行和第 32 行合并后如下所示:
<Schedule><xsl:attribute name="contentId">
理论上,这在功能上应该是等同的,但旧版 MSXML 似乎有点特殊。
我正在进行非常标准的 XSLT 转换。使用 MSXML(在 Oxygen XML 编辑器中)时,我得到以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<ProgramSchedules mediaCompanyID="00001" date="2017-06-08" channel="00019">
<Schedules>
<Schedule contentId="T17ADiamond008P2AA" startTime="06:29:56" endTime="06:30:11" rerun="true" eventType="AP">
</Schedule>
<Schedule contentId="T17AOslo-Sk236s1AA" startTime="06:30:11" endTime="06:30:31" rerun="true" eventType="AP">
</Schedule>
MSXML 4 和 Saxon 显示以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<ProgramSchedules mediaCompanyID="00001" date="2017-06-08" channel="00019">
<Schedules>
<Schedule contentId="T17ADiamond008P2AA" startTime="06:29:56" endTime="06:30:11" rerun="true" eventType="AP"></Schedule>
<Schedule contentId="T17AOslo-Sk236s1AA" startTime="06:30:11" endTime="06:30:31" rerun="true" eventType="AP"></Schedule>
这里的问题是我的 XML 模式没有验证第一个输出,因为 CRLF 出现在开始标记之后。
有没有办法在不更换处理器的情况下解决这个问题?
这是我的样式表的样子:
<?xml version='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:template match="/">
<ProgramSchedules>
<xsl:attribute name="mediaCompanyID">
<xsl:text>00001</xsl:text>
</xsl:attribute>
<xsl:attribute name="date">
<xsl:apply-templates select="txevents/search-criteria/dateselection/ES_DATESELECTION/firstvalue/ESP_DATE"/>
</xsl:attribute>
<xsl:attribute name="channel">
<xsl:choose>
<xsl:when test="starts-with(txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name, 'NRK1')">
<xsl:text>00019</xsl:text>
</xsl:when>
<xsl:when test="txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name = 'NRK2'">
<xsl:text>00029</xsl:text>
</xsl:when>
<xsl:when
test="txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name = 'NRK3' or txevents/ES_BMTXEVENT/channel/ESP_CHANNEL/@name = 'SUPER'">
<xsl:text>00039</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>0</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<Schedules>
<xsl:for-each select="txevents/ES_BMTXEVENT">
<Schedule>
<xsl:attribute name="contentId">
<xsl:value-of select="translate(@productcode, '/', '')"/>
<xsl:value-of select="substring(transmission/ES_TRANSMISSION/@productVersionAsString, 2, 4)"/>
</xsl:attribute>
<xsl:attribute name="startTime">
<xsl:apply-templates select="starttime/ESP_TIMEDURATION"/>
</xsl:attribute>
<xsl:attribute name="endTime">
<xsl:apply-templates select="endtime/ESP_TIMEDURATION"/>
</xsl:attribute>
<xsl:attribute name="rerun">
<xsl:choose>
<xsl:when
test="(transmission/ES_TRANSMISSION/@tx_isrepeat = 'true') or (transmission/ES_TRANSMISSION/@tx_isrerun = 'true')">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="eventType">
<xsl:choose>
<xsl:when
test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Segment of program'">
<xsl:text>RP</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Trailer'">
<xsl:text>AP</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Sting/Vignett'">
<xsl:text>RP</xsl:text>
</xsl:when>
<xsl:when
test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Klokke NRK1 m/ tekst'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Klokke NRK Super'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Klokke NRK2'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Plakater 3'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'A1 fl on'">
<xsl:text>AP</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'Sponsor'">
<xsl:text>BR</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'TTV-rulle NRK1'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:when test="timeallocation/ES_BMTIMEALLOCATION/type/ESP_BMTIMEALLOCATIONTYPE/@name = 'TTV-rulle NRK2'">
<xsl:text>IF</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>US</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute></Schedule>
</xsl:for-each>
</Schedules>
</ProgramSchedules>
</xsl:template>
<xsl:template match="ESP_TIMEDURATION">
<xsl:value-of select="format-number(@hours, '00')"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="format-number(@minutes, '00')"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="format-number(@seconds, '00')"/>
</xsl:template>
<xsl:template match="ESP_DATE">
<xsl:value-of select="@year"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@month, '00')"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@day, '00')"/>
</xsl:template>
<xsl:template match="ESP_TIMEINSTANT">
<xsl:value-of select="@year"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@month, '00')"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="format-number(@day, '00')"/>
</xsl:template>
</xsl:stylesheet>
原始 XML 数据在这里:https://pastebin.com/RWGEi59c
在 Oxygen XML v17.1 中进行的一些实验表明,对 XSL 进行简单的更改就可以摆脱烦人的换行符。
在您的 XSL 代码的第 31 行,您有一条插入 <Schedule>
元素的指令,后跟一个换行符和第 32 行:
<Schedule>
<xsl:attribute name="contentId">
删除第 31 行末尾的换行符,这样第 31 行和第 32 行合并后如下所示:
<Schedule><xsl:attribute name="contentId">
理论上,这在功能上应该是等同的,但旧版 MSXML 似乎有点特殊。