使用命名空间将 xslt 应用于 xml
Applying xslt to xml with a namespace
我知道已经有多个关于这个主题的问题得到了回答,我已经阅读了其中的几个并尝试实施这些建议,但到目前为止没有成功。
我正在尝试创建一个 xsl 以应用于 xml。 xml 来自 P2 相机卡并具有命名空间声明。
我已将命名空间声明添加到我的 xsl,但我似乎仍然无法 select 我想要的元素。
我的 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>
但是,我似乎永远无法 select 我想要的节点,要么导致一个空文件,其中只有我的新元素,要么(通过上述迭代)一个包含的文件所有的值,但不是元素本身。
我使用xsl v1.0,我绝不是xsl专家(这可能表明)所以我不确定问题是否在于我的 Xpath 声明、命名空间或两者的组合。
您没有使用正确的命名空间。 xsi
是属性的前缀,旨在将 XML 架构附加到您的文档。您的文档绑定到具有 urn:schemas-Professional-Plug-in:P2:ClipMetadata:v3.1
URI 的命名空间。
您需要像这样修改样式表:
<?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-namespace
并且不需要为所有内容添加前缀,例如通过使用这个:
<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" />
...
等等
我知道已经有多个关于这个主题的问题得到了回答,我已经阅读了其中的几个并尝试实施这些建议,但到目前为止没有成功。
我正在尝试创建一个 xsl 以应用于 xml。 xml 来自 P2 相机卡并具有命名空间声明。
我已将命名空间声明添加到我的 xsl,但我似乎仍然无法 select 我想要的元素。
我的 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>
但是,我似乎永远无法 select 我想要的节点,要么导致一个空文件,其中只有我的新元素,要么(通过上述迭代)一个包含的文件所有的值,但不是元素本身。
我使用xsl v1.0,我绝不是xsl专家(这可能表明)所以我不确定问题是否在于我的 Xpath 声明、命名空间或两者的组合。
您没有使用正确的命名空间。 xsi
是属性的前缀,旨在将 XML 架构附加到您的文档。您的文档绑定到具有 urn:schemas-Professional-Plug-in:P2:ClipMetadata:v3.1
URI 的命名空间。
您需要像这样修改样式表:
<?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-namespace
并且不需要为所有内容添加前缀,例如通过使用这个:
<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" />
...
等等