如何在XSLT中遍历XML参数

3

我有一个XML文件,通过XSLT进行转换。我通过C#将XML作为参数传递给XSLT。参数的名称是attachment,它包含XML。它的编写方式如下:

StringWriter sw = new StringWriter(); 
XmlTextWriter w = new XmlTextWriter(sw); 
w.WriteStartElement("root"); 
if (!string.IsNullOrEmpty(sWordFileName)) { 
    w.WriteStartElement("mylink", sWordFileName); 
    w.WriteEndElement(); 
}
if (!string.IsNullOrEmpty(sPDFFileName)) { 
    w.WriteStartElement("mylink", sPDFFileName);
    w.WriteEndElement();
}
w.Close();
XPathDocument doc = new XPathDocument(new StringReader(sw.ToString()));
XPathNavigator nav = doc.CreateNavigator();
_exportSet[currentExportSet].Format.ParamList["attachment"] = nav.Select("./*");

我的 XML 参数看起来像这样:
<root><attachment xmlns=file1><attachment xmlns=file2></root>

现在在XSLT中,我需要遍历这个XML参数并创建一个链接。

以下是我的XSLT代码:

<?xml version="1.0" encoding="utf-8"?> 
    <xsl:stylesheet version="2.0" xmlns:xsl="w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
        xmlns:my-scripts="urn:my-scripts" 
        xmlns="factiva.com/fcs/schemas/newsSummaries">

        <xsl:param name="attachment"/>
        <xsl:for-each select="$attachment">  
            <a target="_blank" href="#"><xsl:copy-of select="."/></a>  
         </xsl:for-each>
     </xsl:stylesheet>

但它并不创建链接。

你为什么要问你的“代码”不工作的原因?你声称传递到转换的参数的实际值甚至不是一个格式良好的XML文档--在你想将其加载到XmlDocument中的时候,你应该会得到一个异常。更不用说XSLT样式表了。最好的建议是,你需要阅读并学习至少XML、XPath和XSLT的基础知识。 - Dimitre Novatchev
现在问题已经明确定义为MS特定的XSLT处理器。我认为@Dimitre可以提供帮助。 - user357812
5个回答

2
XSLT参数与XML标签名称不同。使用描述here<xsl:param>标签传递参数。
如下方评论所述,这个问题与上面提供的链接提供的问题并没有太大区别。
StringWriter sw = new StringWriter(); 
XmlTextWriter w = new XmlTextWriter(sw); 
w.WriteStartElement("root"); 
if (!string.IsNullOrEmpty(sWordFileName)) { 
    w.WriteStartElement("attachment", sWordFileName); 
    w.WriteAttributeString("name", sWordFileName);
    w.WriteEndElement(); 
}
if (!string.IsNullOrEmpty(sPDFFileName)) { 
    w.WriteStartElement("attachment");
    w.WriteAttributeString("name", sPDFFileName);
    w.WriteEndElement();
}
w.WriteEndElement();
w.Close();
XPathDocument doc = new XPathDocument(new StringReader(sw.ToString()));
XPathNavigator nav = doc.CreateNavigator();

XsltArgumentList xslArg = new XsltArgumentList();
xslArg.AddParam("attachment","",nav);

这里将是XSL匹配每个 访问包含标记的参数的代码:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
   xmlns:xsl="w3.org/1999/XSL/Transform"
   xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
   xmlns:my-scripts="urn:my-scripts" 
   xmlns="factiva.com/fcs/schemas/newsSummaries">
    <xsl:param name="attachment" />

    <xsl:template match="/">
        <xsl:apply-templates select="$attachment"/>
    </xsl:template>
    <xsl:template match="attachment">
        <a target="_blank" href="{@name}">{@name}</a>
    </xsl:template>

</xsl:stylesheet>

@jatin - 根据我找到的内容进行了更新,但您可能希望将此信息添加到您的问题中,以便其他人可以回答并可能更改您的标签以包括C#。 - justkt
@justkt:将XML节点集作为参数传递是可以的。请不要让人们感到困惑! - user357812
将节点集作为参数传递对于结构化数据(如地图)非常方便。 - user357812
这是我如何将参数传递给XSLT的方式:StringWriter sw = new StringWriter(); XmlTextWriter w = new XmlTextWriter(sw); w.WriteStartElement("root");if (!string.IsNullOrEmpty(sWordFileName)) { w.WriteStartElement("mylink", sWordFileName); w.WriteEndElement(); }if (!string.IsNullOrEmpty(sPDFFileName)) { w.WriteStartElement("mylink", sPDFFileName); w.WriteEndElement(); }w.Close();XPathDocument doc = new XPathDocument(new StringReader(sw.ToString())); XPathNavigator nav = doc.CreateNavigator(); _exportSet[currentExportSet].Format.ParamList["attachment"] = nav.Select("./*");请问我有做错什么吗? - jvm
@justkt:你的代码没有解决问题,因为它没有传递节点集参数。请修正一下。 - user357812
显示剩余12条评论

2
应该写成 <xsl:for-each select="attachment">...。之所以没有 $ 符号,是因为 attachment 是 XML 元素的名称,而不是变量。
在您提供完整的 XSLT 和 XML 后,需要进行编辑。
您的 XML 存在几个问题:
  • 所有标记都应该关闭。
  • 您不能将 xmlns 用于除命名空间之外的任何其他内容。
  • 属性值必须用双引号括起来。
因此,XML 文件的正确版本应该是(例如):
<root>
  <attachment ptr="file1" />
  <attachment ptr="file2" />
</root>

XSLT文件也存在一些问题:

  • xsl命名空间应该绑定到确切的URI http://www.w3.org/1999/XSL/Transform
  • 您必须至少有一个模板,以便XSLT转换处理您的输入XML文档。

例如,正确的版本如下:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/root">
    <xsl:for-each select="attachment">  
      <a target="_blank" href="{@ptr}"><xsl:value-of select="@ptr" /></a>  
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

我不确定这是否正是你想要的,但对于上述文件,它生成了以下片段:
<a target="_blank" href="file1">file1</a>
<a target="_blank" href="file2">file2</a>

@ChrisJпјљattachment XPathиЎЁиѕѕејЏдјљйЂ‰ж‹©дёЉдё‹ж–‡иЉ‚з‚№зљ„attachmentе­ђиЉ‚з‚№пј€жњЄдЅїз”ЁеЏ‚ж•°еј•з”Ёпј‰гЂ‚ - user357812
@Alejandro:在你添加完整的XSLT之后,我已经更新了答案。 - ChrisJ
@ChrisJ:现在更好了。你写道:“您必须至少有一个模板,以便XSLT转换处理输入XML文档”。这是不正确的,请进行测试。除此之外,您还没有回答问题标题。 - user357812
@Alejandro:我用xsltproc测试了你的文件(不是用C#),但是它确实无法工作;处理器报告了上述错误……请明确告诉我们你的问题是什么,期望的结果是什么。 - ChrisJ
@ChrisJ:我不是原帖发布者,@jatin才是。 - user357812
@Alejandro:糟糕,对此感到抱歉。那么,Jatin,请告诉我们这个答案是否有帮助,并且如果没有,您期望得到什么样的答案。 - ChrisJ

2

你可以将任何XPath / XSLT数据类型作为参数传递。如何实现完全取决于XSLT处理器的实现。

作为证明,此样式表可与任何输入(未使用)一起使用:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="attachment" select="document('parameter.xml')/root"/>
    <xsl:template match="/">
        <xsl:apply-templates select="$attachment"/>
    </xsl:template>
    <xsl:template match="attachment">
        <a target="_blank" href="{@href}">Link</a>
    </xsl:template>
</xsl:stylesheet>

parameter.xml 资源作为:

<root>
    <attachment href="file1"/>
    <attachment href="file2"/>
</root> 

输出:

<a target="_blank" href="file1">Link</a>
<a target="_blank" href="file2">Link</a>

0
您需要将包含链接的属性值放在这里:
<xsl:value-of select="@YourAttribute"/>

这个操作选择了当前xml元素的一个属性。


0
你发布的代码有些错误。引号在哪里?$attachment是什么? 你可能忘记了提及命名空间,为了正确选择,你需要写成select="//file1:attachment"或类似的形式。

附件作为参数传递,其中包含XML。 - jvm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接