设计模板XSLT以生成XML时出错

时间:2017-07-11 21:31:51

标签: c# xml xslt

我需要生成这个XML:

<bdo_fosfec:RegistrosPagosElement xsi:type="bdo_fosfec:RegistrosPagos" 
 xmlns:bdo_fosfec="http://asocajas.app.com/example" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <registro54 xsi:type="bdo_fosfec:Registro54">
   <registro82 xsi:type="bdo_fosfec:Registro82">
     <C512>39756656</C512>
     <C614>YAXMINNI</C614>
   </registro82>
 </registro54>
 <registro54 xsi:type="bdo_fosfec:Registro54">
   <registro82 xsi:type="bdo_fosfec:Registro82">
     <C512>79374740</C512>
     <C614>VICTOR</C614>
   </registro82>
 </registro54>
</bdo_fosfec:RegistrosPagosElement>

我构建了这个XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
 <xsl:template match="/">
   <bdo_fosfec:RegistrosPagosElement xsi:type="bdo_fosfec:RegistrosPagos" xmlns:bdo_fosfec="http://asocajas.app.com/example" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:apply-templates select="registro54"/>
   </bdo_fosfec:RegistrosPagosElement>
 </xsl:template>
 <!--TEMPLATE REGISTRO 54-->
 <xsl:template match="registro54">
   <registro54 xsi:type="bdo_fosfec:Registro54">
        <registro82 xsi:type="bdo_fosfec:Registro82">
          <C512><xsl:value-of select="C512"/></C512>
          <C614><xsl:value-of select="C614"/></C614>
        </registro82>
   </registro54>
 </xsl:template>
</xsl:stylesheet>

但是,当我在C#上加载我的XSLT时,我收到错误。

var xslt = new XslCompiledTransform();
xslt.Load(myxslt);
  

XSLT编译错误。 &#39;的xsi&#39;是未声明的前缀。第11行,第19位。

好像&#34; xsi&#34;第二个模板无法达到第一个模板的定义。我该如何修复我的XSLT?

我对XSLT进行了一些修改,但没有生成我想要的结果,xslt设计的正确性是什么?

1 个答案:

答案 0 :(得分:2)

XSL中的命名空间(和前缀)可能很棘手。

您需要声明要在XSL代码中使用的任何命名空间。由于您的XSL以有限的方式声明了前缀为xsi的命名空间,因此当XSL处理器出现在声明范围之外时,它不能处理此前缀,因此会抛出错误。

尝试将xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"添加到XSL中最顶层的xsl:stylesheet元素。打破这个:

  • xmlns代表“ XML n ame s ”。
  • xsi是您要使用的前缀。这可以是任何东西 - 它不必匹配输入XML中的前缀。
  • http://www.w3.org/2001/XMLSchema-instance部分是标识命名空间的URI字符串。此部分必须匹配输入XML中的命名空间URI,否则您的模板将无法匹配。

我注意到你 在另一个元素上添加名称空间声明:bdo_fosfec:RegistrosPagosElement。这是有效的XSL,此命名空间仅适用于此元素的子元素。 xsi前缀(指向此命名空间)也用于XSL代码中的不同模板,并且由于bdo_fosfec:RegistrosPagosElement中的命名空间声明的范围未扩展到此其他模板, XSL处理器无法正确编译代码。

修复后会是什么样子:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <bdo_fosfec:RegistrosPagosElement xsi:type="bdo_fosfec:RegistrosPagos"
            xmlns:bdo_fosfec="http://asocajas.app.com/example">
            <xsl:apply-templates select="registro54"/>
        </bdo_fosfec:RegistrosPagosElement>
    </xsl:template>

    <!--TEMPLATE REGISTRO 54-->
    <xsl:template match="registro54">
        <registro54 xsi:type="bdo_fosfec:Registro54">
            <registro82 xsi:type="bdo_fosfec:Registro82">
                <C512><xsl:value-of select="C512"/></C512>
                <C614><xsl:value-of select="C614"/></C614>
            </registro82>
        </registro54>
    </xsl:template>
</xsl:stylesheet>