XSLT在同一路径上添加元素

XSLT在同一路径上添加元素,xslt,Xslt,考虑以下XML: <?xml version="1.0" encoding="ISO-8859-1"?> <catalog> <cd> <title>Empire Burlesque</title> <artist> <name>Bob</name> <surname>Dylan</surname

考虑以下XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>
            <name>Bob</name>
            <surname>Dylan</surname>
        </artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

皇帝讽刺剧
上下快速移动
迪伦
美国
哥伦比亚
10.90
1985
我想使用XSLT将元素添加到此XML中,以获得以下结果:

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>
            <name>Bob</name>
            <surname>Dylan</surname>
            <!-- NEW -->
            <middlename>???</middlename>
        </artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
        <!-- NEW -->
        <comment>great one</comment>
    </cd>
    <!-- NEW -->
    <cd>
      <title>Hide your heart</title>
        <artist>
          <name>Bonnie</name>
          <surname>Tyler</surname>
        </artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
</catalog>

皇帝讽刺剧
上下快速移动
迪伦
???
美国
哥伦比亚
10.90
1985
伟大的
隐藏你的心
邦妮
泰勒
英国
哥伦比亚唱片公司
9.90
1988
为了实现这一点,我编写了以下XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template name="injectXml">
    <xsl:param name="whatToInject"/>
    <xsl:copy>
      <xsl:copy-of select="node() | @*"/>
      <xsl:copy-of select="$whatToInject"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//catalog">
    <xsl:call-template name="injectXml">
      <xsl:with-param name="whatToInject">
        <cd>
          <title>Hide your heart</title>
            <artist>
              <name>Bonnie</name>
              <surname>Tyler</surname>
            </artist>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
        </cd>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="//cd[year=1985]">
    <xsl:call-template name="injectXml">
      <xsl:with-param name="whatToInject">
        <comment>great one</comment>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="//cd[year=1985]/artist">
    <xsl:call-template name="injectXml">
      <xsl:with-param name="whatToInject">
        <middlename>???</middlename>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>

</xsl:stylesheet>

隐藏你的心
邦妮
泰勒
英国
哥伦比亚唱片公司
9.90
1988
伟大的
???
为什么它不起作用?怎么做?

你试过了吗


match=“//cd/year/[.='1985']”此转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my"
 exclude-result-prefixes="my xsl"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:updates>
   <update num="1">
    <comment>great one</comment>
   </update>
   <update num="2">
    <middlename>XXX</middlename>
   </update>
   <update num="3">
    <cd>
      <title>Hide your heart</title>
        <artist>
          <name>Bonnie</name>
          <surname>Tyler</surname>
        </artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
   </update>
 </my:updates>

 <xsl:output omit-xml-declaration="yes"/>
    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="catalog">
      <xsl:call-template name="inject">
       <xsl:with-param name="pUpdate" select="3"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template match="cd[year=1985]">
      <xsl:call-template name="inject">
       <xsl:with-param name="pUpdate" select="1"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template match="cd[year=1985]/artist">
      <xsl:call-template name="inject">
       <xsl:with-param name="pUpdate" select="2"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="inject">
      <xsl:param name="pUpdate"/>

      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
       <xsl:apply-templates select=
       "document('')/*/my:updates/*[@num=$pUpdate]/node()"/>
      </xsl:copy>
    </xsl:template>

  <xsl:template match="*[ancestor::my:updates]">
        <xsl:element name="{name()}" namespace="{namespace-uri()}">
          <xsl:copy-of select=
             "namespace::*[not(name()='my' or name()='xsl')]"/>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
  </xsl:template>
</xsl:stylesheet>
<catalog>
   <cd>
      <title>Empire Burlesque</title>
      <artist>
         <name>Bob</name>
         <surname>Dylan</surname>
         <middlename>XXX</middlename>
      </artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
      <comment>great one</comment>
   </cd>
   <cd>
      <title>Hide your heart</title>
      <artist>
         <name>Bonnie</name>
         <surname>Tyler</surname>
      </artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
</catalog>

伟大的
XXX
隐藏你的心
邦妮
泰勒
英国
哥伦比亚唱片公司
9.90
1988
应用于提供的XML文档时:

<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>
            <name>Bob</name>
            <surname>Dylan</surname>
        </artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

皇帝讽刺剧
上下快速移动
迪伦
美国
哥伦比亚
10.90
1985
生成所需的正确结果

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my"
 exclude-result-prefixes="my xsl"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:updates>
   <update num="1">
    <comment>great one</comment>
   </update>
   <update num="2">
    <middlename>XXX</middlename>
   </update>
   <update num="3">
    <cd>
      <title>Hide your heart</title>
        <artist>
          <name>Bonnie</name>
          <surname>Tyler</surname>
        </artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
   </update>
 </my:updates>

 <xsl:output omit-xml-declaration="yes"/>
    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="catalog">
      <xsl:call-template name="inject">
       <xsl:with-param name="pUpdate" select="3"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template match="cd[year=1985]">
      <xsl:call-template name="inject">
       <xsl:with-param name="pUpdate" select="1"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template match="cd[year=1985]/artist">
      <xsl:call-template name="inject">
       <xsl:with-param name="pUpdate" select="2"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="inject">
      <xsl:param name="pUpdate"/>

      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
       <xsl:apply-templates select=
       "document('')/*/my:updates/*[@num=$pUpdate]/node()"/>
      </xsl:copy>
    </xsl:template>

  <xsl:template match="*[ancestor::my:updates]">
        <xsl:element name="{name()}" namespace="{namespace-uri()}">
          <xsl:copy-of select=
             "namespace::*[not(name()='my' or name()='xsl')]"/>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
  </xsl:template>
</xsl:stylesheet>
<catalog>
   <cd>
      <title>Empire Burlesque</title>
      <artist>
         <name>Bob</name>
         <surname>Dylan</surname>
         <middlename>XXX</middlename>
      </artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
      <comment>great one</comment>
   </cd>
   <cd>
      <title>Hide your heart</title>
      <artist>
         <name>Bonnie</name>
         <surname>Tyler</surname>
      </artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
</catalog>

皇帝讽刺剧
上下快速移动
迪伦
XXX
美国
哥伦比亚
10.90
1985
伟大的
隐藏你的心
邦妮
泰勒
英国
哥伦比亚唱片公司
9.90
1988

似乎不适合我。你能解释一下它应该做什么吗?好问题(+1)。请参阅我的答案以获得完整的解决方案。我认为XSLT很容易。。。谢谢你的回答!不幸的是,我使用的工具不支持ducument()函数。是否有一种解决方法(更改XSLT)?@Stefan:XSLT确实很简单。当更新实际上在一个单独的文档中时,我在此解决方案中执行的名称空间清理是不必要的。@Stefan:每个兼容的XSLT处理器都支持
document()
函数。也许你只是不知道如何启用它。您使用的是什么XSLT处理器?我将XSLT与WiX一起使用。WiX将.NET库用于XSLT。默认情况下,.NET库禁用document()函数和脚本。要在WiX中启用此功能,我需要更改它的源代码。。。我需要让它工作,所以我通过破解DLL修复了WiX。