【问题标题】:Can't get debug output correctly using XSLT/XPath 2.0无法使用 XSLT/XPath 2.0 正确获取调试输出
【发布时间】:2012-03-16 10:29:47
【问题描述】:

我有一个这样的 XML:

<?xml version="1.0" encoding="UTF-8"?>

<Section>
    <Chapter>
        <Cell colname="1">
            <Value>A</Value>
        </Cell>
        <Cell colname="2">
            <MyValue>AAA</MyValue>
            <MyValue>BBB</MyValue>
        </Cell>
        <Cell colname="3">
            <MyCar>Honda</MyCar>
        </Cell>
    </Chapter>
    <Chapter>
        <Cell colname="1">
            <Value>C</Value>
        </Cell>
        <Cell colname="2">
            <MyValue>CCC</MyValue>
        </Cell>
        <Cell colname="3">
            <MyCar>Toyota</MyCar>
        </Cell>
    </Chapter>
</Section>

我有一个这样的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates select="Section/Chapter"/>
    </xsl:template>

    <xsl:template match="Chapter">
        <xsl:apply-templates select="./Cell/MyValue"/>
    </xsl:template>

    <xsl:template match="MyValue">
        <xsl:message>
            <xsl:value-of select="../../Cell/@colname"/>
            <xsl:value-of select="../../Cell[@colname='1']/Value"/>
            <xsl:value-of select="."/>
            <xsl:value-of select="../../Cell[@colname='3']/MyCar"/>
        </xsl:message>
    </xsl:template>

    <xsl:template match="text()" />

</xsl:stylesheet>

问题是调试输出显示为 1 2 3 A AAA Honda 1 2 3 A BBB Honda 1 2 3 C CCC Toyota。我想要 1 A 2 AAA 3 Honda 1 A 2 BBB 3 Honda 1 C 2 CCC 3 Toyota。基本上正确获取属性colname的值。

那么几个问题:

  1. 我做错了什么?
  2. 有一个序列 1 2 3 生成为什么?。

TIA,

约翰

【问题讨论】:

    标签: xslt xslt-2.0 xpath-2.0


    【解决方案1】:

    那么几个问题:

    1. 我做错了什么?

    您没有准确指定必要的表达式。

    1. 有一个序列 1 2 3 生成为什么?。

    因为../../Cell/@colname 选择了当前节点的祖父Chapter每个 Cell 子节点的colname 属性。

    解决方案

    使用

    <xsl:template match="MyValue">
        <xsl:message>
            <xsl:value-of select="../../Cell[1]/@colname"/>
            <xsl:value-of select="../../Cell[@colname='1']/Value"/>
            <xsl:value-of select="../@colname"/>
            <xsl:value-of select="."/>
            <xsl:value-of select="../../Cell[3]/@colname"/>
            <xsl:value-of select="../../Cell[@colname='3']/MyCar"/>
        </xsl:message>
    </xsl:template>
    

    调试输出正是想要的

    1A2AAA3Honda
    1A2BBB3Honda
    1C2CCC3Toyota
    

    您也可以对上一个问题的答案稍作修改

    <xsl:stylesheet version="2.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         xmlns:xs="http://www.w3.org/2001/XMLSchema">
         <xsl:output omit-xml-declaration="yes" indent="yes"/>
         <xsl:strip-space elements="*"/>
    
         <xsl:template match="Chapter">
          <xsl:apply-templates select="Cell[1]"/>
         </xsl:template>
    
         <xsl:template match="Cell">
          <xsl:param name="pText" as="xs:string*"/>
    
          <xsl:apply-templates select="*[1]">
           <xsl:with-param name="pText" select="$pText"/>
          </xsl:apply-templates>
         </xsl:template>
    
         <xsl:template match="Cell/*">
          <xsl:param name="pText" as="xs:string*"/>
    
          <xsl:variable name="vText" as="xs:string*"
           select="$pText, ../@colname, string(.)"/>
    
          <xsl:sequence select=
           "$vText
              [not(current()/../following-sibling::Cell)]"/>
          <xsl:apply-templates select="../following-sibling::Cell[1]">
            <xsl:with-param name="pText" select="$vText"/>
          </xsl:apply-templates>
          <xsl:apply-templates select="following-sibling::*">
            <xsl:with-param name="pText" select="$pText"/>
          </xsl:apply-templates>
         </xsl:template>
    </xsl:stylesheet>
    

    当此转换应用于提供的 XML 文档时

    <Section>
        <Chapter>
            <Cell colname="1">
                <Value>A</Value>
            </Cell>
            <Cell colname="2">
                <MyValue>AAA</MyValue>
                <MyValue>BBB</MyValue>
            </Cell>
            <Cell colname="3">
                <MyCar>Honda</MyCar>
            </Cell>
        </Chapter>
        <Chapter>
            <Cell colname="1">
                <Value>C</Value>
            </Cell>
            <Cell colname="2">
                <MyValue>CCC</MyValue>
            </Cell>
            <Cell colname="3">
                <MyCar>Toyota</MyCar>
            </Cell>
        </Chapter>
    </Section>
    

    产生想要的正确结果

    1 A 2 AAA 3 Honda 1 A 2 BBB 3 Honda 1 C 2 CCC 3 Toyota
    

    【讨论】:

    • Dimitre:感谢您的回答,就我的原始代码而言,需要添加或修复什么?我是一个新手,有时看着像你这样的复杂代码我会觉得头晕目眩:(。
    • @JohnX:我多次编辑了我的答案——现在您可以看到对原始代码的更正。
    • Dimitre:再次感谢您的好意!。
    【解决方案2】:

    以下会产生预期的结果:

    1. 您得到 1 2 3 是因为 ../../Cell/@colname 匹配当前章节中的所有三个单元格。这就是我将其更改为 Cell[1]
    2. 的原因
    3. 我不确定 colname 应该如何“硬编码”,例如,使用 colname 3 来查找 colname 的值 3 似乎很奇怪。这就是为什么我只是将其输出为文本

    ?xml 版本="1.0" 编码="UTF-8"?>

    <xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>
    
    <xsl:template match="/">
        <xsl:apply-templates select="Section/Chapter"/>
    </xsl:template>
    
    <xsl:template match="Chapter">
        <xsl:apply-templates select="./Cell/MyValue"/>
    </xsl:template>
    
    <xsl:template match="MyValue">
        <xsl:message>
            <xsl:value-of select="../../Cell[1]/@colname"/>
            <xsl:value-of select="../../Cell[@colname='1']/Value"/>
            <xsl:value-of select="../@colname"/>
            <xsl:value-of select="."/>
            <xsl:text>3</xsl:text>
            <xsl:value-of select="../../Cell[@colname='3']/MyCar"/>
        </xsl:message>
    </xsl:template>
    
    <xsl:template match="text()" />
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多