尝试漂亮地打印XSLT输出时出现问题

尝试漂亮地打印XSLT输出时出现问题,xslt,pretty-print,Xslt,Pretty Print,这是我的第一篇文章,所以请让我知道,如果我可以使它更具建设性的任何方式。我已经阅读了论坛指南,所以如果我无意中打断了它们,那只会是一个无辜的错误 问题 这是一个简单的例子: 如何打印XSL文件的输出? 但有一些标准: 仅使用本机XSL功能。 无需使用第二个XSL文件进行“第二次传递”。 它还必须适用于混合内容的元素。 我在谷歌上搜索过这个问题,但没有找到一个明确的答案。我只使用了XSL大约一周,所以如果我在其他地方不知何故错过了答案,请放心 一个例子 这个XML <email>

这是我的第一篇文章,所以请让我知道,如果我可以使它更具建设性的任何方式。我已经阅读了论坛指南,所以如果我无意中打断了它们,那只会是一个无辜的错误

问题 这是一个简单的例子:

如何打印XSL文件的输出?

但有一些标准:

  • 仅使用本机XSL功能。
  • 无需使用第二个XSL文件进行“第二次传递”。
  • 它还必须适用于混合内容的元素。
  • 我在谷歌上搜索过这个问题,但没有找到一个明确的答案。我只使用了XSL大约一周,所以如果我在其他地方不知何故错过了答案,请放心


    一个例子 这个XML

    <email>
        <attachedItem>priceless photograph.jpg</attachedItem>
        <attachedItem>important document.doc</attachedItem>
        <attachedItem>access codes.pdf</attachedItem>
    </email>
    
    
    无价照片
    重要文件.doc
    访问代码.pdf
    
    …由此XSL转换

    <!-- Pretty Print Output -->
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/">
    <email>
        "Please find attached the stuff."
        <xsl:apply-templates/>
    </email>
    </xsl:template>
    
    <xsl:template match="attachedItem">
        <xsl:copy/>
    </xsl:template>
    
    
    “请找到附件中的资料。”
    
    …产生这个结果

    <?xml version="1.0" encoding="utf-8"?>
    <email>
            "Please find attached the stuff."
            <attachedItem>priceless photograph.jpg</attachedItem>
       <attachedItem>important document.doc</attachedItem>
       <attachedItem>access codes.pdf</attachedItem>
    </email>
    
    
    “请找到附件中的资料。”
    无价照片
    重要文件.doc
    访问代码.pdf
    
    使用Saxon6.5.5引擎

    期望输出
    
    “请找到附件中的资料。”
    无价照片
    重要文件.doc
    访问代码.pdf
    

    我自己在这个问题上的进展 从上面的XSL中,您将看到我发现了
    的用法。这符合前2个标准,但不符合第3个标准。换句话说,它生成了漂亮的打印XML,没有混合的内容,但是通过它,我收到了您可以在上面看到的不想要的输出

    我知道我得到这个输出的原因是源XML中保留空白的方式。如果空白是包含其他非空白字符的文本节点的一部分,则无论
    指令如何,它始终保留空白。然而,尽管我理解,我仍然无法想出解决办法

    虽然我自己已经解决了前两个标准,但我仍然想知道这是否是实现漂亮打印结果的最佳方法

    提前谢谢

    您可以在

    
    

    这将产生我对您期望的结果的假设,如果不是,请发布一个“期望的输出”示例/

    以下样式表正好生成您请求的输出。转换是用Saxon 6.5.5执行的。只有仔细键入所有换行符(
    &&10;
    )和空格(
    &&32;
    )字符,才能实现正确的缩进

    请注意,当涉及文本内容时,漂亮打印XML没有任何意义。元素标记的缩进可以很容易地控制,但是具有混合内容的元素的文本节点总是一个问题。以XML作为输入的应用程序永远不应该依赖于XML中文本内容的精确缩进或空白处理

    一般来说,在XSLT样式表中直接输出文本被认为是一个坏主意。始终将文本内容放入
    xsl:text
    xsl:strip space
    仅对属于输入XML文档的元素的纯空白文本节点有效(正如@TobiasKlevenz所建议的)

    样式表

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <!-- Pretty Print Output -->
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/">
    <email>
        <xsl:text>&#10;&#32;&#32;&#32;"Please find attached the stuff."&#10;&#32;&#32;&#32;</xsl:text>
        <xsl:apply-templates/>
    </email>
    </xsl:template>
    
    <xsl:template match="attachedItem|text()">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    
    </xsl:transform>
    
    <?xml version="1.0" encoding="utf-8"?>
    <email>
       "Please find attached the stuff."
       <attachedItem>priceless photograph.jpg</attachedItem>
       <attachedItem>important document.doc</attachedItem>
       <attachedItem>access codes.pdf</attachedItem>
    </email>
    
    
    
       “请查找附件中的内容。”
       
    
    输出

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <!-- Pretty Print Output -->
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/">
    <email>
        <xsl:text>&#10;&#32;&#32;&#32;"Please find attached the stuff."&#10;&#32;&#32;&#32;</xsl:text>
        <xsl:apply-templates/>
    </email>
    </xsl:template>
    
    <xsl:template match="attachedItem|text()">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    
    </xsl:transform>
    
    <?xml version="1.0" encoding="utf-8"?>
    <email>
       "Please find attached the stuff."
       <attachedItem>priceless photograph.jpg</attachedItem>
       <attachedItem>important document.doc</attachedItem>
       <attachedItem>access codes.pdf</attachedItem>
    </email>
    
    
    “请找到附件中的资料。”
    无价照片
    重要文件.doc
    访问代码.pdf
    
    您希望您的输出是什么样的?也许能证明这一点。我不认为xsl:strip空间在这里有什么区别,因为它只处理输入XML,而不处理您自己用样式表硬编码的文本。您可以尝试的第一件事是在电子邮件文本周围添加xsl:text
    “请查找附件。”
    您的输出不会反映在显示的样式表中。您展示了一个生成文本
    apply templates
    copy
    元素的元素,因为它们没有前缀。@Mathias Müller啊,是的,很抱歉,这只是一个拼写错误,我在帖子中更正了它。@TobiasKlevenz感谢您的回复,匹配
    会导致每行之间有一个额外的回车符。我相信这是因为它们将从源XML中保留下来。您好@tolanj,谢谢您的回答,不幸的是,这并没有产生所需的输出,它导致顶部的行看起来像这样
    “请查找附件。”无价照片.jpg
    。全部在一条线上,没有回车。我在我的文章中添加了一个“想要的输出”部分来解释。感谢全面的回答“马蒂亚斯Mü勒”,我会考虑现在回答的问题。不过有一件小事,我很想知道为什么您要匹配“attachedItem/text()”而不是“attachedItem”?我认为后者的效果与
    导致
    递归复制所有子节点的效果相同。这应该可以复制文本节点,而不必对它们进行“匹配”。我不匹配
    attachedItem/text()
    ,匹配在
    attachedItem | text()
    ,这意味着模板同时匹配
    attachedItem
    元素和文本节点。不管怎样,文本节点都是输出的,这是对的,但这是因为输出文本节点是撒克逊的默认行为。应用模板与复制非常不同,它不复制任何内容。相反,它指示处理器执行类似的操作:“对于当前匹配的任何剩余子节点,查找您选择的其他模板”。因此,如果您只是复制节点而不进行任何更改,那么
    text()
    的匹配实际上是多余的,但更明确的是提到它。我刚刚注意到您的第一个答复。我知道t