使用多个源XML文件的Nokogiri XSLT转换



我想使用Nokogiri翻译XML。我构建了一个XSL,一切都很好。我还在Intellij中测试了它。我的数据来自两个XML文件。

当我试图让野村做变换时,我的问题就出现了。我似乎找不到一种方法来解析多个源文件。

这是我在文档中使用的代码:

require 'Nokogiri'
doc1 = Nokogiri::XML(File.read('F:/transcoder/xslt_repo/core_xml.xml',))
xslt = Nokogiri::XSLT(File.read('F:/transcoder/xslt_repo/google.xsl'))
puts xslt.transform(doc1)

我试过了:

require 'Nokogiri'
doc1 = Nokogiri::XML(File.read('F:/transcoder/xslt_repo/core_xml.xml',))
doc2 = Nokogiri::XML(File.read('F:/transcoder/xslt_repo/file_data.xml',))
xslt = Nokogiri::XSLT(File.read('F:/transcoder/xslt_repo/test.xsl'))
puts xslt.transform(doc1,doc2)

然而,transform似乎只需要一个参数,所以目前我只能解析我需要的一半数据:

<?xml version="1.0"?>
<package package_id="LB000001">
  <asset_metadata>
    <series_title>test asset 1</series_title>
    <season_title>Number 1</season_title>
    <episode_title>ET 1</episode_title>
    <episode_number>1</episode_number>
    <license_start_date>21-07-2016</license_start_date>
    <license_end_date>31-07-2016</license_end_date>
    <rating>15</rating>
    <synopsis>This is a test asset</synopsis>
  </asset_metadata>
  <video_file>
    <file_name/>
    <file_size/>
    <check_sum/>
  </video_file>
  <image_1>
    <file_name/>
    <file_size/>
    <check_sum/>
  </image_1>
</package>

我怎样才能让它发挥作用?

编辑:

这是core_metadata.xml,它是通过PHP代码块创建的,数据来自数据库。

<?xml version="1.0" encoding="utf-8"?>
<manifest task_id="00000000373">
  <asset_metadata>
    <material_id>LB111111</material_id>
    <series_title>This is a test</series_title>
    <season_title>This is a test</season_title>
    <season_number>1</season_number>
    <episode_title>that test</episode_title>
    <episode_number>2</episode_number>
    <start_date>23-08-2016</start_date>
    <end_date>31-08-2016</end_date>
    <ratings>15</ratings>
    <synopsis>this is a test</synopsis>
  </asset_metadata>
  <file_info>
    <source_filename>LB111111</source_filename>
    <number_of_segments>2</number_of_segments>
    <segment_1 seg_1_start="00:00:10.000" seg_1_dur="00:01:00.000"/>
    <segment_2 seg_2_start="00:02:00.000" seg_2_dur="00:05:00.000"/>
<conform_profile definition="hd" aspect_ratio="16f16">ffmpeg -i S_PATH/F_NAME.mp4 SEG_CONFORM 2&gt; F:/Transcoder/logs/transcode_logs/LOG_FILE.txt</conform_profile>
<transcode_profile profile_name="xbox" package_type="tar">ffmpeg -f concat -i T_PATH/CONFORM_LIST TRC_PATH/F_NAME.mp4 2&gt; F:/Transcoder/logs/transcode_logs/LOG_FILE.txt</transcode_profile>
    <target_path>F:/profiles/xbox</target_path>
  </file_info>
</manifest>

第二个XML(file_date.XML)由nokogiri在transcode过程中动态创建:

<?xml version="1.0"?>
<file_data>
  <video_file>
    <file_name>LB111111_xbox_230816114438.mp4</file_name>
    <file_size>141959922</file_size>
    <md5_checksum>bac7670e55c0694059d3742285079cbf</md5_checksum>
  </video_file>
  <image_1>
    <file_name>test</file_name>
    <file_size>test</file_size>
    <md5_checksum>test</md5_checksum>
  </image_1>
</file_data>

我设法解决了这个问题,通过将file_date.xml硬编码到XSLT文件中来调用:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
    <package>
        <xsl:attribute name="package_id">
            <xsl:value-of select="manifest/asset_metadata/material_id"/>
        </xsl:attribute>
        <asset_metadata>
            <series_title>
                <xsl:value-of select="manifest/asset_metadata/series_title"/>
            </series_title>
            <season_title>
                <xsl:value-of select="manifest/asset_metadata/season_title"/>
            </season_title>
            <episode_title>
                <xsl:value-of select="manifest/asset_metadata/episode_title"/>
            </episode_title>
            <episode_number>
                <xsl:value-of select="manifest/asset_metadata/episode_number"/>
            </episode_number>
            <license_start_date>
                <xsl:value-of select="manifest/asset_metadata/start_date"/>
            </license_start_date>
            <license_end_date>
                <xsl:value-of select="manifest/asset_metadata/end_date"/>
            </license_end_date>
            <rating>
                <xsl:value-of select="manifest/asset_metadata/ratings"/>
            </rating>
            <synopsis>
                <xsl:value-of select="manifest/asset_metadata/synopsis"/>
            </synopsis>
        </asset_metadata>
        <video_file>
            <file_name>
                <xsl:value-of select="document('file_data.xml')/file_data/video_file/file_name"/>
            </file_name>
            <file_size>
                <xsl:value-of select="document('file_data.xml')/file_data/video_file/file_size"/>
            </file_size>
            <check_sum>
                <xsl:value-of select="document('file_data.xml')/file_data/video_file/md5_checksum"/>
            </check_sum>
        </video_file>
        <image_1>
            <file_name>
                <xsl:value-of select="document('file_data.xml')/file_data/image_1/file_name"/>
            </file_name>
            <file_size>
                <xsl:value-of select="document('file_data.xml')/file_data/image_1/file_size"/>
            </file_size>
            <check_sum>
                <xsl:value-of select="document('file_data.xml')/file_data/image_1/md5_checksum"/>
            </check_sum>
        </image_1>
    </package>
</xsl:template>

然后我使用Saxon进行转换:

xslt = "java -jar C:/SaxonHE9-7-0-7J/saxon9he.jar #{temp}core_metadata.xml #{temp}#{profile}.xsl > #{temp}#{file_name}.xml"
system("#{xslt}")

我很想找到一种不用将file_date.xml硬编码到XSLT中的方法。

合并XML文档和转换

在XLS转换之前,您必须做一些工作来组合XML内容@锡人对档案中的一个类似问题有一个很好的答案,可以根据您的用例进行调整。

假设我们有以下样本内容:

<!--a.xml-->
<?xml version="1.0"?>
<xml>
  <packages>
    <package>Data here for A</package>
    <package>Another Package</package>  
  </packages>
</xml>
<!--a.xml-->
<!--b.xml-->
<?xml version="1.0"?>
<xml>
  <packages>
    <package>B something something</package>  
  </packages>
</xml>
<!--end b.xml-->

我们希望应用以下XLST模板:

<!--transform.xslt-->
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//packages">
  <html>
  <body>
    <h2>Packages</h2>
    <ol>
      <xsl:for-each select="./package">
        <li><xsl:value-of select="text()"/></li>
      </xsl:for-each>
    </ol>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>
<!--end transform.xslt-->

如果我们有并行的文档结构,就像在本例中一样,我们可以将两个XML文档的内容合并在一起,并将其传递进行转换。

require 'Nokogiri'
doc1 = Nokogiri::XML(File.read('./a.xml'))
doc2 = Nokogiri::XML(File.read('./b.xml'))
moved_packages = doc2.search('package')
doc1.at('/descendant::packages[1]').add_child(moved_packages)
xslt = Nokogiri::XSLT(File.read('./transform.xslt'))
puts xslt.transform(doc1)

这将产生以下输出:

<html><body>
<h2>Packages</h2>
<ol>
<li>Data here for A</li>
<li>Another Package</li>
<li>B something something</li>
</ol>
</body></html>

如果您的XML文档具有不同的结构,那么您可能会受益于将内容添加到的中间XML节点集,而不是将文档2的内容合并到文档1的快捷方式。

相关内容

  • 没有找到相关文章

最新更新