xml - 如何为两个xml文件添加合并模板?

标签 xml xslt xslt-1.0

.xml 中的第一个 xml 文件:

<conf title="co" attr01="val01">
  <c attr02="val02">
    <Item key="db" attr03="val03">
    <m1 />
      <s>
        <m2 />
        <Item key="1">
        <m3 />
          <sp>
            <Chart />
          </sp>
        </Item>
        <m4 />
        <Item key="2">
          <sp>
            <m5 />
            <Chart />
          </sp>
        </Item>
        <Item key="3">
          <sp>
            <Chart />
          </sp>
        </Item>
        <m6 />
      </s>
    </Item>
  </c>
</conf>

第二个 xml 文件 profile.xml,它使用有关小部件的信息完成第一个文件:

<p title="profile">
  <c>
    <Item key="db">
      <s>
        <Item key="1">
          <sp>
            <Chart>
                <Widget title="widget12">
                    <Test title="test1"/>
                </Widget>
            </Chart>
          </sp>
        </Item>
        <Item key="2">
          <sp>
            <Chart>
                <Widget title="widget32">
                    <Test title="test3"/>
                </Widget>
            </Chart>
          </sp>
        </Item>
        <Item key="3">
          <sp>
            <Chart>
                <Widget title="widget54">
                    <Test title="test6"/>
                </Widget>
            </Chart>
          </sp>
        </Item>
      </s>
    </Item>
  </c>
</p>

profile.xml 文件与 in.xml 的不同之处在于它具有不同的根标记名称,每个 Chart 标记都有相应的子 Widget 标记,文件中仅存在与 Chart 标记相关的父标记,并且除root 和 Widget 只有关键属性。

转换后,结果文件与原始文件的区别仅在于 Chart 标签的 Widget 子标签:

<conf title="co" attr01="val01">
  <c attr02="val02">
    <Item key="db" attr03="val03">
    <m1 />
      <s>
        <m2 />
        <Item key="1">
        <m3 />
          <sp>
            <Chart>
                <Widget title="widget12">
                    <Test title="test1"/>
                </Widget>
            </Chart>
          </sp>
        </Item>
        <m4 />
        <Item key="2">
          <sp>
            <m5 />
            <Chart>
                <Widget title="widget32">
                    <Test title="test3"/>
                </Widget>
            </Chart>
          </sp>
        </Item>
        <Item key="3">
          <sp>
            <Chart>
                <Widget title="widget54">
                    <Test title="test6"/>
                </Widget>
            </Chart>
          </sp>
        </Item>
        <m6 />
      </s>
    </Item>
  </c>
</conf>

现在有一个不完整的 XSLT1.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:param name="fileName" select="'profile.xml'" />
  <xsl:param name="updates" select="document($fileName)" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="p">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

如何重写“p”模板XSLT1.0?

最佳答案

试试这个:

convert.xsl

<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:strip-space elements="*"/>
  <xsl:param name="fileName" select="'profile.xml'" />
  <xsl:param name="updates" select="document($fileName)" />
  
  <!--transform starts here on input XML-->
  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>
  
  <!--rules for general nodes()-->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!--special rule for Chart elements-->      
  <xsl:template match="Chart">
    <xsl:variable name="context" select="."/>
    <xsl:if test="$updates//Item/@key = $context/ancestor-or-self::Item[1]/@key">
      <xsl:copy-of select="($updates//Item[@key = $context/ancestor-or-self::Item[1]/@key])//Chart"/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

输出.xml

<?xml version="1.0" encoding="UTF-8"?>
<conf title="co" attr01="val01">
   <c attr02="val02">
      <Item key="db" attr03="val03">
         <m1/>
         <s>
            <m2/>
            <Item key="1">
               <m3/>
               <sp>
                  <Chart>
                     <Widget title="widget12">
                        <Test title="test1"/>
                     </Widget>
                  </Chart>
               </sp>
            </Item>
            <m4/>
            <Item key="2">
               <sp>
                  <m5/>
                  <Chart>
                     <Widget title="widget32">
                        <Test title="test3"/>
                     </Widget>
                  </Chart>
               </sp>
            </Item>
            <Item key="3">
               <sp>
                  <Chart>
                     <Widget title="widget54">
                        <Test title="test6"/>
                     </Widget>
                  </Chart>
               </sp>
            </Item>
            <m6/>
         </s>
      </Item>
   </c>
</conf>

如果需要,您可以将参数 profile.xml 更改为其他参数...

关于xml - 如何为两个xml文件添加合并模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71333577/

相关文章:

android - 为什么这一行 xmlns :android ="http://schemas.android.com/apk/res/android" must be the first in the layout xml file?

c++ - Xerces DOMNode 将节点名称返回为#Text

java - 我的 EditFriendsActivity 中没有出现 ActionBar。我的代码有什么问题?

xslt - 如何查找带连字符的单词?

javascript - 在 Internet Explorer 中缓存客户端 XSLT 导入

xml - 如何向 Gradle 的 eclipse 任务的类路径添加注释

xml - 可以更好地控制 xsl/xpath 中的 for-each 吗?

XSLT 拆分输出文件 - muenchian 分组

xslt - 将连续的后代节点合并为一个

javascript - javascript 中的大于运算符在 xslt 中不起作用