2

可能重复:
XSLT 用于 XML 元素中的替换属性,如果它存在于另一个 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 帮助我。我认为我们需要将第二个 XML 作为参数传递给 XSLT,我正在尝试这样做。我对 XSLT 很陌生,所以可能没有正确编码。关于我们如何做到这一点的任何意见都会有所帮助。提前致谢。

4

3 回答 3

6

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

这是可能的,但根本没有必要

一种更方便的方法是将文档的文件路径传递给转换,并使用 XSLTdocument()函数来解析和访问它:

<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>
于 2012-07-04T16:15:57.853 回答
1

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

于 2012-07-04T12:48:59.343 回答
1

你应该看看这个document()功能。将 XML 树作为参数传入是一些 XML 系统,而不是其他系统。

如果您有一个变量,例如

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

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

编辑

只是为了清楚我对 Dimitre Novatchev 的回答,正如我所说,你可以做到,尽管在 90% 的情况下你会想要使用文档函数,但可以将节点片段从 C# 传递到样式表使用 AddParam 的应用程序,并且可以在您从自己的应用程序生成该数据时使用,并且不需要编写它(或在不实用的地方)。

因此,对于样式表,例如:

    <?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>

第一个和第二个 XML 根据您的原始问题,您可以使用传递节点,例如:

        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());
        }

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

于 2012-07-04T12:54:47.643 回答