将xml作为参数传递给xslt并替换xml

时间:2012-07-04 12:38:46

标签: xslt

  

可能重复:
  XSLT for replace attribute in XML element if it exists in another XML?

我有两个XML:

第一个XML:

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

第二个XML:

<SecondXML>
  <catalog>
         <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
  </catalog>
</SecondXML>

我想使用XSLT转换我的第一个XML。第一个xml的cd节点应替换为第二个xml的cd节点。

XSLT转换产生的XML:

<FirstXML>
  <catalog>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
  </catalog>
</FirstXML>

请为此帮助我使用XSLT。我想我们需要将Second XML作为参数传递给XSLT,我试图这样做。我是XSLT的新手,所以可能无法正确编码。 关于我们如何做到这一点的任何意见都会有所帮助。在此先感谢。

3 个答案:

答案 0 :(得分:6)

  

我认为我们需要将Second XML作为参数传递给   XSLT。

这是可能的,但根本不是必需的

更方便的方法是将文件路径传递给文档,并使用XSLT document() 函数进行解析和访问:

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

 <xsl:param name="pDocLink" select=
  "'file:///c:/temp/delete/SecondXml.xml'"/>

 <xsl:template match="/*">
  <xsl:copy>
   <xsl:copy-of select="document($pDocLink)/*/*[1]"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

在提供的“第一个”文档上应用此转换时

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

,“第二个”文档位于:c:\temp\delete\SecondXml.xml

<SecondXML>
    <catalog>
        <cd>
            <title>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
        </cd>
    </catalog>
</SecondXML>

产生了想要的正确结果

<FirstXML>
   <catalog>
      <cd>
         <title>Hide your heart</title>
         <artist>Bonnie Tyler</artist>
         <country>UK</country>
         <company>CBS Records</company>
         <price>9.90</price>
         <year>1988</year>
      </cd>
   </catalog>
</FirstXML>

答案 1 :(得分:1)

有一个document函数,用它来处理几个输入源。 您的问题描述太模糊,无法提出更详细的建议。尝试搜索一些教程,例如http://www.ibm.com/developerworks/xml/library/x-tipcombxslt/

答案 2 :(得分:1)

您应该查看document()功能。将XML树作为参数传递的是一些XML系统,而不是其他系统。

如果你有一个变量,如

<xsl:variable name="source" select="document('filename.xml')//catalog"/>

然后访问变量$source将为您提供CD分支的根

修改

为了清楚我对Dimitre Novatchev的回答,正如我所说,你可以做到这一点,虽然你有90%的时间想要使用文档功能,但是可以将节点片段传递给样式表。来自具有AddParam的C#应用​​程序,并且可以在从您自己的应用程序生成数据时使用,并且不需要编写它(或者它不适用的地方)。

对于样式表,例如:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
        <xsl:output method="xml" indent="yes"/>

        <xsl:param name="bonnie_tyler"/>

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

        <xsl:template match="cd[ancestor::FirstXML]">
                <xsl:copy>
                    <xsl:apply-templates select="msxsl:node-set($bonnie_tyler)//cd/*"/>
                </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>

根据您的原始问题,您可以使用传递节点,如:

        try
        {
            XslCompiledTransform xt = new XslCompiledTransform();
            Assembly ass = Assembly.GetEntryAssembly();
            Stream strm = ass.GetManifestResourceStream("ConsoleApplication1.testparam.xslt");
            XmlTextReader xmr = new XmlTextReader(strm);
            xt.Load(xmr);
            xmr.Close();

            XmlDocument originalDocument = new XmlDocument();
            strm = ass.GetManifestResourceStream("ConsoleApplication1.FirstXML.xml");
            originalDocument.Load(strm);
            XmlDocument replacementNode = new XmlDocument();
            strm = ass.GetManifestResourceStream("ConsoleApplication1.SecondXML.xml");
            replacementNode.Load(strm);

            XsltArgumentList arg = new XsltArgumentList();
            arg.AddParam("bonnie_tyler", "", replacementNode);

            StringBuilder htmlOutput = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(htmlOutput);

            xt.Transform(originalDocument, arg, writer);

            Console.Out.Write(htmlOutput.ToString());
        }

它会为您提供所需的输出(尽管显然您不会像这里那样从磁盘加载文件)