C# 为什么在SOAP头中包含某些内容会阻止它与XSLT模板匹配?
我有一个类似这样的SOAP(1.1)信封:C# 为什么在SOAP头中包含某些内容会阻止它与XSLT模板匹配?,c#,xml,xslt,soap,C#,Xml,Xslt,Soap,我有一个类似这样的SOAP(1.1)信封: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3"> <soapenv:Header> <l3:requestType>Valid</l3:requestType> </soapenv:Header> <
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3">
<soapenv:Header>
<l3:requestType>Valid</l3:requestType>
</soapenv:Header>
<soapenv:Body>
<l3:xyzRequest xsi:schemaLocation="http://tempuri.org/l3 lds.xsd " requestId="7291655" functionalId="1645885" appChannel="XYZ" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<workpackageId>126381</workpackageId>
...
</l3:xyzRequest>
</soapenv:Body>
</soapenv:Envelope>
<xsl:template match="soapenv:Envelope/soapenv:Body/l3:xyzRequest">
...
</xsl:template>
有效的
126381
...
XSLT模板如下所示:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3">
<soapenv:Header>
<l3:requestType>Valid</l3:requestType>
</soapenv:Header>
<soapenv:Body>
<l3:xyzRequest xsi:schemaLocation="http://tempuri.org/l3 lds.xsd " requestId="7291655" functionalId="1645885" appChannel="XYZ" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<workpackageId>126381</workpackageId>
...
</l3:xyzRequest>
</soapenv:Body>
</soapenv:Envelope>
<xsl:template match="soapenv:Envelope/soapenv:Body/l3:xyzRequest">
...
</xsl:template>
...
我正在Visual Studio 2013(.NET Framework 4.5.1)中使用C#。以下是转换代码:
XslCompiledTransform xslt = new XslCompiledTransform(false);
StringBuilder sb = new StringBuilder();
xslt.Load(@"<XSLTPath>");
using (XmlWriter xw = XmlWriter.Create(sb, xslt.OutputSettings))
{
xslt.Transform(XML.CreateReader(), xw);
}
xslcomiledtransform xslt=新的xslcomiledtransform(false);
StringBuilder sb=新的StringBuilder();
Load(@“”);
使用(xmlwriterxw=XmlWriter.Create(sb,xslt.OutputSettings))
{
Transform(XML.CreateReader(),xw);
}
当我运行转换时,模板是不匹配的,但是如果我从SOAP头中删除
元素(不做任何其他更改),它可以正常工作。有人知道为什么吗
编辑:
根据提供更多代码的请求,以下是重现问题的最小示例:
using System;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Xsl;
namespace Project1
{
class Program
{
static void Main()
{
XDocument XSL = XDocument.Parse("<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:l3=\"http://tempuri.org/l3\" version=\"1.0\">" +
"<xsl:output method=\"xml\" />" +
"<xsl:template match=\"soapenv:Envelope/soapenv:Body/l3:xyzRequest\">" +
"<Test><xsl:value-of select=\"workpackageId\" /></Test>" +
"</xsl:template>" +
"</xsl:stylesheet>");
XDocument XML = XDocument.Parse("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:l3=\"http://tempuri.org/l3\">" +
"<soapenv:Header>" +
"<l3:requestType>Valid</l3:requestType>" +
"</soapenv:Header>" +
"<soapenv:Body>" +
"<l3:xyzRequest xsi:schemaLocation=\"http://tempuri.org/l3 lds.xsd \" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
"<workpackageId>126381</workpackageId>" +
"</l3:xyzRequest>" +
"</soapenv:Body>" +
"</soapenv:Envelope>");
XslCompiledTransform xslt = new XslCompiledTransform(false);
StringBuilder sb = new StringBuilder();
xslt.Load(XSL.CreateReader());
using (XmlWriter xw = XmlWriter.Create(sb, xslt.OutputSettings))
{
xslt.Transform(XML.CreateReader(), xw);
}
Console.WriteLine(sb.ToString());
Console.ReadLine();
}
}
}
使用系统;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
使用System.Xml.Xsl;
命名空间项目1
{
班级计划
{
静态void Main()
{
XDocument XSL=XDocument.Parse(“”)+
"" +
"" +
"" +
"" +
"");
XDocument XML=XDocument.Parse(“”)+
"" +
“有效”+
"" +
"" +
"" +
"126381" +
"" +
"" +
"");
XslCompiledTransform xslt=新XslCompiledTransform(false);
StringBuilder sb=新的StringBuilder();
Load(XSL.CreateReader());
使用(xmlwriterxw=XmlWriter.Create(sb,xslt.OutputSettings))
{
Transform(XML.CreateReader(),xw);
}
Console.WriteLine(sb.ToString());
Console.ReadLine();
}
}
}
如果运行该命令,模板将不匹配,并且您将获得返回所有节点值的默认行为:Valid126381
;但是,如果您注释掉第21行(“Valid”+
),模板将匹配,您将得到预期结果:126381
编辑2:
哎呀,我刚刚注意到我上面发布的第一个结果不是默认行为,但它不是格式良好的XML,这让我很反感。很抱歉,复制和粘贴时应该仔细看看!我想现在的问题是:当一个元素包含在SOAP头中时,为什么返回它的值,即使它不是来自XSLT模板?最明显的可能原因是,用于匹配输入中l3:xyzRequest元素的模板可能不会产生任何结果:
- 输入可能没有任何l3:xyzRequest元素。如果您显示的输入片段是正确的,这不是您的问题
- 模板上的匹配模式可能与预期的元素不匹配;这可能是由拼写错误的名称、绑定命名空间前缀的错误或XPath表达式公式中的问题造成的。乍一看,这似乎不是你的问题
- 样式表可能永远不会要求处理器处理该元素。(更具体地说:可能没有xsl:apply-templates指令包含它选择的节点中的l3:xyzRequest元素。)如果没有完整查看样式表,就无法确认这是问题的原因,但也不能排除
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:l3="http://tempuri.org/l3">
<soapenv:Header>
<l3:requestType>Valid</l3:requestType>
</soapenv:Header>
<soapenv:Body>
<l3:xyzRequest xsi:schemaLocation="http://tempuri.org/l3 lds.xsd "
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<workpackageId>126381</workpackageId>
</l3:xyzRequest>
</soapenv:Body>
</soapenv:Envelope>
有效的
126381
要使用此XSLT进行处理,请执行以下操作:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:l3="http://tempuri.org/l3" version="1.0">
<xsl:output method="xml" />
<xsl:template
match="soapenv:Envelope/soapenv:Body/l3:xyzRequest">
<Test><xsl:value-of select="workpackageId"/></Test>
</xsl:template>
</xsl:stylesheet>
在此XML上运行此样式表将生成以下输出:
<?xml version="1.0"?>
Valid
<Test xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3">126381</Test>
有效的
126381
我不清楚你为什么认为模板不匹配
字符串“Valid”出现在输出中,因为您没有覆盖内置的默认模板(通过在子元素上循环来处理元素,通过将文本节点复制到输出来处理文本节点)。请向我们显示两行以上的XSLT。你给我们看的部分不是问题所在。谢谢你提供的信息,我很抱歉没有说得更清楚!XSLT已经被削减到最低限度,但从我发布的内容来看,这并不明显。我已经用一个完整的代码示例编辑了我的文章,我希望这将使问题易于重现。再次感谢您的帮助!谢谢你的解释。我没有意识到它在一个元素的所有子元素上都是递归的。