首页 > 解决方案 > 使用命名空间将 xslt 应用于 xml

问题描述

我知道关于这个主题已经有多个已回答的问题,我已经阅读了其中的几个并尝试实施这些建议,但到目前为止还没有成功。

我正在尝试创建一个 xsl 以应用于 xml。xml 来自 P2 相机卡并具有命名空间声明。

我已经向我的 xsl 添加了一个命名空间声明,但我似乎仍然无法选择我想要的元素。

我的 xsl 看起来像这样(它的当前迭代)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:schemas-Professional-Plug-in:P2:ClipMetadata:v3.1">
<xsl:output method="xml" indent="yes" />

    <xsl:template match="/xsi:P2Main">

<xsl:element name="clip">
  <video>
  <codec>
    <xsl:value-of select="xsi:ClipContent/xsi:EssenceList/xsi:Video/xsi:Codec" />
    </codec>
    <byteoffset>
    <xsl:value-of select="/xsi:P2Main/xsi:ClipContent/xsi:EssenceList/xsi:Video/xsi:VideoIndex/xsi:StartByteOffset" />
    </byteoffset>
    <bytecount>
    <xsl:value-of select="//xsi:Video/xsi:VideoIndex/xsi:DataSize" />
    </bytecount>
     <starttimecode>
     <xsl:value-of select="//xsi:Video/xsi:StartTimeCode" />
      </starttimecode>
      <framerate>
     <xsl:value-of select="//xsi:Video/xsi:FrameRate" /> 
      </framerate>
    </video>
  </xsl:element>
    </xsl:template>
    </xsl:stylesheet>

我试图转换的 xml 看起来像这样(不是完整的文件):

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<P2Main xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:schemas-Professional-Plug-in:P2:ClipMetadata:v3.1">
  <ClipContent>
    <ClipName>0002CC</ClipName>
    <GlobalClipID>060A2B340101010501010D43130000005E4D83E9398105D4008045826CF62010</GlobalClipID>
    <Duration>220</Duration>
    <EditUnit>1001/24000</EditUnit>
    <EssenceList>
      <Video ValidAudioFlag="false">
        <VideoFormat>MXF</VideoFormat>
        <Codec Class="100">AVC-I_1080/29.97p</Codec>
        <FrameRate>23.98p</FrameRate>
        <StartTimecode>08:24:36:04</StartTimecode>
        <StartBinaryGroup>A30F24C3</StartBinaryGroup>
        <AspectRatio>16:9</AspectRatio>
        <VideoIndex>
          <StartByteOffset>32768</StartByteOffset>
          <DataSize>103854592</DataSize>
        </VideoIndex>
      </Video>
      <Audio>
        <AudioFormat>MXF</AudioFormat>
        <SamplingRate>48000</SamplingRate>
        <BitsPerSample>16</BitsPerSample>
        <AudioIndex>
          <StartByteOffset>32768</StartByteOffset>
          <DataSize>880880</DataSize>
        </AudioIndex>
      </Audio>
      <Audio>
        <AudioFormat>MXF</AudioFormat>
        <SamplingRate>48000</SamplingRate>
        <BitsPerSample>16</BitsPerSample>
        <AudioIndex>
          <StartByteOffset>32768</StartByteOffset>
          <DataSize>880880</DataSize>
        </AudioIndex>
      </Audio>

但是,我似乎永远无法选择我想要的节点,要么导致一个空文件,其中只有我的新元素,要么(通过上述迭代)一个包含所有值但不包含元素的文件他们自己。

必须使用 xsl v1.0,而且我绝不是 xsl 专家(这可能表明),所以我不确定问题是由于我的 Xpath 声明、命名空间还是两者的组合。

标签: xmlxsltxslt-1.0xml-namespaces

解决方案


您没有使用正确的命名空间。xsi是旨在将 XML 模式附加到文档的属性的前缀。您的文档通过urn:schemas-Professional-Plug-in:P2:ClipMetadata:v3.1URI 绑定到命名空间。

您需要像这样修改样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:P2="urn:schemas-Professional-Plug-in:P2:ClipMetadata:v3.1">
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="/P2:P2Main">

  <xsl:element name="clip">
    <video>
      <codec>
        <xsl:value-of select="P2:ClipContent/P2:EssenceList/P2:Video/P2:Codec" />
    </codec>
    <byteoffset>
    <xsl:value-of select="/P2:P2Main/P2:ClipContent/P2:EssenceList/P2:Video/P2:VideoIndex/P2:StartByteOffset" />
    </byteoffset>
    <bytecount>
    <xsl:value-of select="//P2:Video/P2:VideoIndex/xsi:DataSize" />
    </bytecount>
     <starttimecode>
     <xsl:value-of select="//P2:Video/P2:StartTimeCode" />
      </starttimecode>
        <framerate>
          <xsl:value-of select="//P2:Video/P2:FrameRate" /> 
        </framerate>
      </video>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

如果您使用的是 XSL-T 1.0,则需要为路径中的所有元素@select@match上面的属性添加前缀。

使用 XSL-T 2.0 或更高版本,您可以使用xpath-default-namespaceand 不需要为所有内容添加前缀,例如使用以下命令:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xpath-default-namespace="urn:schemas-Professional-Plug-in:P2:ClipMetadata:v3.1">

  <xsl:template match="/P2Main">
     ...
     <xsl:value-of select="ClipContent/EssenceList/Video/Codec" />
     ... 

等等


推荐阅读