如何将包含多个xml:base属性的xml保存到多个文件

时间:2018-07-31 13:43:13

标签: xml xslt xquery

我有一个类似于以下文件的xml文件:

<main xmlns:xi="http://www.w3.org/2001/XInclude">
  <level1 xml:base="./include1/include1.xml">
    <level2 xml:base="./include1/include2/include2.xml">
      <level3 xml:base="./include2/include3/include3.xml">
        <level4 xml:base="./include3/include4/include4.xml">
          <data>0</data>
          <data>1</data>
        </level4>
      </level3>
    </level2>
  </level1>
</main> 

该文件是通过使用xi:include组装多个xml文件而生成的。 特别是,示例中的文件由以下文件生成:

./ main.xml

<?xml version="1.0" encoding="UTF-8" ?>
<main  xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="./include1/include1.xml" />
</main >

./ include1 / include1.xml

<?xml version="1.0" encoding="UTF-8" ?>
<level1  xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="./include2/include2.xml" />
</level1 > 

./ include1 / include2 / include2.xml

<?xml version="1.0" encoding="UTF-8" ?>
<level2  xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="./include3/include3.xml" />
</level2 > 

./ include1 / include2 / include3 / include3.xml

<?xml version="1.0" encoding="UTF-8" ?>
<level3  xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="./include4/include4.xml" />
</level3 > 

./ include1 / include2 / include3 / include4 / include4.xml

<?xml version="1.0" encoding="UTF-8" ?>
<level4  xmlns:xi="http://www.w3.org/2001/XInclude">
    <data> 0 </data>
    <data> 1 </data>
</level4 > 

现在,在对输出文件中的数据进行一些处理之后,我想保存回原始文件,以检索原始文件夹树结构。

我试图编写自己的XQuery脚本来实现此目标,方法是在输出文件中重复出现,处理存储在 xml:base 属性中的值并保存文件。

但是,现在,在编写了150行以上的初学者级XQuery代码之后,我感到很茫然。

因此,我想知道是否有人已经开发了一些实现此功能的XQuery或XSLT代码(我认为总体上应该是一个非常通用的功能...),或者我是否可以使用一些现有的库来执行此任务。 谢谢

1 个答案:

答案 0 :(得分:1)

我认为您可以使用类似的东西在XSLT中轻松完成

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:mode on-no-match="shallow-copy">
  <xsl:template match="*[@xml:base]">
    <xi:include href="{@xml:base}"/>
    <xsl:result-document href="{@xml:base}">
      <xsl:copy>
        <xsl:copy-of select="@* except @xml:base"/>
        <xsl:apply-templates/>
      </xsl:copy>
    </xsl:result-document>
  </xsl:template>
</xsl:transform> 

我看不到如何在缺少xsl:result-document的XQuery中做到这一点。

唯一的困难是使hrefxsl:result-document元素上的xi:include属性值正确。按照我写的方式,@xml:base属性中的相对URI将针对转换的基本输出URI进行解析。使用base-uri(.)的值可能会得到更好的结果,该值可以针对祖先的基础URI对其进行解析,但是问题在于,该URL可能是与源文档位于同一目录中的绝对URI。也许使用base-uri(.)加上一些前缀前缀使其相对,或者也许使用OutputURIResolver重定向最终输出位置。