2

我有一个 XML 文件,其中父元素上的属性驱动子元素转换的逻辑。

当我在 Notepad++ 的 XML 工具插件中应用这个 XSLT 转换时,我得到了正确和预期的结果。但是,当我使用XslCompiledTransform结果时,就好像它缺少声明的变量一样。我尝试在 Visual Studio 中调试 XSLT,变量的值始终为NULL.

我在 .NET 中做错了什么?

XML:

 <summary>
   <section format="2" title="ACCOUNT SUMMARY">
        <section_box>
          <subTotal>
            <description>BALANCE FORWARD</description>
            <amount />
          </subTotal>
          <line>
            <description>Previous Balance</description>
            <amount>$155.64</amount>
          </line>
          <line>
            <description>Payments Received</description>
            <amount>$155.64 CR</amount>
          </line>
          <subTotal>
            <description>TOTAL BALANCE FORWARD</description>
            <amount>$0.00</amount>
          </subTotal>
        </section_box>
   </section>
   <section format="3" title="ACCOUNT DETAILS">
        <section_box>
          <line>        <label>Charge</label>
            <description>Monthly Charge for Service</description>
            <amount>$155.64</amount>
          </line>
          <subTotal>
            <description>TOTAL NEW BALANCE</description>
            <amount>$155.64</amount>
          </subTotal>
        </section_box>
   </section>
 </summary>

XSLT:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
    <xsl:template match="summary">
        <summary>
            <xsl:apply-templates select="section" />
        </summary>
    </xsl:template>
    <xsl:template match="section">
        <xsl:variable name="row-format" select="@format" />
        <xsl:if test="@title">
            <title>
                <xsl:value-of select="@title" />
            </title>
        </xsl:if>
        <xsl:apply-templates select="line|subTotal|section_box">
            <xsl:with-param name="row-format" select="$row-format" />
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="line">
        <xsl:param name="row-format" />
        <line>
            <xsl:attribute name="format">
                <xsl:value-of select="$row-format"/>
            </xsl:attribute>
            <xsl:if test="$row-format = '2'">
                <description>
                    <xsl:value-of select="description" />
                </description>
                <date>
                    <xsl:value-of select="date" />
                </date>
                <amount>
                    <xsl:value-of select="amount" />
                </amount>
            </xsl:if>
            <xsl:if test="$row-format = '3'">
                <label>
                    <xsl:value-of select="label" />
                </label>
                <description>
                    <xsl:value-of select="description" />
                </description>
                <amount>
                    <xsl:value-of select="amount" />
                </amount>
            </xsl:if>
        </line>
    </xsl:template>
    <xsl:template match="subtotal|subTotal">
        <xsl:param name="row-format" />
        <subtotal>
            <description>
                <xsl:value-of select="description" />
            </description>
            <amount>
                <xsl:value-of select="amount" />
            </amount>
        </subtotal>
    </xsl:template>
</xsl:stylesheet>

预期结果(并且来自 Notepad++,noteline元素的内容和format属性是正确的):

<summary>
    <title>ACCOUNT SUMMARY</title>
    <subtotal>
        <description>BALANCE FORWARD</description>
        <amount/>
    </subtotal>
    <line format="2">
        <description>Previous Balance</description>
        <date/>
        <amount>$155.64</amount>
    </line>
    <line format="2">
        <description>Payments Received</description>
        <date/>
        <amount>$155.64 CR</amount>
    </line>
    <subtotal>
        <description>TOTAL BALANCE FORWARD</description>
        <amount>$0.00</amount>
    </subtotal>
    <title>ACCOUNT DETAILS</title>
    <line format="3">
        <label>Charge</label>
        <description>Monthly Charge for Service</description>
        <amount>$155.64</amount>
    </line>
    <subtotal>
        <description>TOTAL NEW BALANCE</description>
        <amount>$155.64</amount>
    </subtotal>
</summary>

.NET 产生(注意缺少lines 的内容,因为没有找到匹配format项;因为它是NULL):

<summary>
    <title>ACCOUNT SUMMARY</title>
    <subtotal>
        <description>BALANCE FORWARD</description>
        <amount/>
    </subtotal>
    <line format="" />
    <line format="" />
    <subtotal>
        <description>TOTAL BALANCE FORWARD</description>
        <amount>$0.00</amount>
    </subtotal>
    <title>ACCOUNT DETAILS</title>
    <line format="" />
    <subtotal>
        <description>TOTAL NEW BALANCE</description>
        <amount>$155.64</amount>
    </subtotal>
</summary>

.NET 代码执行:

Dim compiled As New XslCompiledTransform(True)
compiled.Load("C:\summary.xsl")
compiled.Transform("C:\Summary.xml", "C:\TransformedSummary.xml")
4

1 回答 1

2

我认为你需要改变

    <xsl:apply-templates select="line|subTotal|section_box">
        <xsl:with-param name="row-format" select="$row-format" />
    </xsl:apply-templates>

    <xsl:apply-templates select="descendant::line|descendant::subTotal">
        <xsl:with-param name="row-format" select="$row-format" />
    </xsl:apply-templates>

或者你需要添加一个模板

<xsl:template match="section_box">
  <xsl:param name="row-format"/>
  <xsl:apply-templates select="*">
    <xsl:with-param name="row-format" select="$row-format"/>
  </xsl:apply-templates>
</xsl:template>

然后你会简单地使用

    <xsl:apply-templates select="section_box">
        <xsl:with-param name="row-format" select="$row-format" />
    </xsl:apply-templates>

使用 XSLT 1.0,参数不会自动通过隧道,因此我认为您当前为代码获得的结果是正确的,您正在尝试将模板应用于line不存在的子元素,因此没有任何反应,然后您将模板应用于 asection_box和传递参数,但由于您没有为该元素编写任何模板,因此默认模板在处理子节点时不会传递参数。因此,当应用您的模板时,line它不会传递参数。

于 2013-09-25T14:34:31.013 回答