【问题标题】:xsl:value-of and xsl:for-each ignored in XSLTxsl:value-of 和 xsl:for-each 在 XSLT 中被忽略
【发布时间】:2017-11-19 12:19:11
【问题描述】:

我尝试使用 XSLT 从 API XML 响应文件中选择属性。
这是返回 XML 文件的请求:http://zoekdienst.overheid.nl/sru/Search?version=1.2&operation=searchRetrieve&x-connection=oep&startRecord=1&maximumRecords=10&query=(keyword=verkeersbesluit) and (creator=groningen) and (organisationType=Provincie)

我创建了以下 XSL 文件:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidop="http://standaarden.overheid.nl/product/terms/" xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <verkeersbesluiten>
            <test>Hello world!</test>
            <numberOfRecords><xsl:value-of select="searchRetrieveResponse/numberOfRecords"/></numberOfRecords>
            <xsl:for-each select="searchRetrieveResponse/records/record/recordData/gzd/originalData/overheidop:meta/overheidop:owmskern">
                <besluit>
                    <test2>Hello world again!</test2>
                    <titel><xsl:value-of select="dcterms:title"/></titel>
                    <locatie><xsl:value-of select="dcterms:spatial"/></locatie>
                </besluit>    
            </xsl:for-each>
        </verkeersbesluiten>
    </xsl:template>
</xsl:stylesheet>

转换后的结果文件:

<?xml version="1.0" encoding="UTF-8"?>
<verkeersbesluiten xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidop="http://standaarden.overheid.nl/product/terms/" xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">
    <test>Hello world!</test>
    <numberOfRecords/>
</verkeersbesluiten>

这不是我想要的结果。那将是:

<?xml version="1.0" encoding="UTF-8"?>
<verkeersbesluiten xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidop="http://standaarden.overheid.nl/product/terms/" xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">
    <test>Hello world!</test>
    <numberOfRecords>41</numberOfRecords>
    <besluit>
        <test2>Hello World again!</test2>
        <titel>Provincie Groningen: verkeersbesluit nieuwe situatie parallelweg langs N964 tussen Winschoten en Scheemda.</titel>
        <locatie>264455 576268$%$Oldambt</locatie>
    </besluit>
    <besluit>
        <test2>Hello World again!</test2>
        <titel>Provincie Groningen: verkeersbesluit nieuwe situatie N366, Westerstraat en A.G. Wildervanckweg in Ter Apel</titel>
        <locatie>266425 544276$%$Vlagtwedde<</locatie>
    </besluit>
    ...
</verkeersbesluiten>

有人可以指出我做错了什么吗?

威利

================================================ =============================

正如@halfbit 所建议的,我已将命名空间 srw 和 sru 添加到我的 XSL 文件中:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:sru="http://standaarden.overheid.nl/sru/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidop="http://standaarden.overheid.nl/product/terms/" xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <verkeersbesluiten>
            <test>Hello world!</test>
            <numberOfRecords><xsl:value-of select="srw:searchRetrieveResponse/srw:numberOfRecords"/></numberOfRecords>
            <xsl:for-each select="srw:searchRetrieveResponse/srw:records/srw:record/sru:gzd">
                <besluit>
                    <test2>Hello world again!</test2>
                </besluit>    
            </xsl:for-each>
        </verkeersbesluiten>
    </xsl:template>
</xsl:stylesheet>

这会导致:

<?xml version="1.0" encoding="UTF-8"?>
<verkeersbesluiten xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:sru="http://standaarden.overheid.nl/sru/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidop="http://standaarden.overheid.nl/product/terms/" xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">
  <test>Hello world!</test>
  <numberOfRecords>41</numberOfRecords>
  <besluit>
    <test2>Hello world again!</test2>
  </besluit>
  <besluit>
    <test2>Hello world again!</test2>
  </besluit>
  ...
</besluiten>

这看起来不错。但是当我扩展 xsl:for-each 子句时出现问题:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:sru="http://standaarden.overheid.nl/sru/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidop="http://standaarden.overheid.nl/product/terms/" xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <verkeersbesluiten>
            <test>Hello world!</test>
            <numberOfRecords><xsl:value-of select="srw:searchRetrieveResponse/srw:numberOfRecords"/></numberOfRecords>
            <xsl:for-each select="srw:searchRetrieveResponse/srw:records/srw:record/sru:gzd">
                <besluit>
                    <test2>Hello world again!</test2>
                </besluit>    
            </xsl:for-each>
        </verkeersbesluiten>
    </xsl:template>
</xsl:stylesheet>

这会导致:

<?xml version="1.0" encoding="UTF-8"?>
<verkeersbesluiten xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:sru="http://standaarden.overheid.nl/sru/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidop="http://standaarden.overheid.nl/product/terms/" xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">
  <test>Hello world!</test>
  <numberOfRecords>41</numberOfRecords>
</verkeersbesluiten>

我无法理解这一点。我做错了什么?

【问题讨论】:

  • 我检查了这个 xml 输入文件并发现了一个警告。 “您文档中从该位置引用的架构包含错误。”xsi:schemaLocation="http://www.loc.gov/zing/srw/ srw-types.xsd"xsi:schemaLocation="http://standaarden.overheid.nl/sru gzd.xsd"
  • XML 输入使用http://www.loc.gov/zing/srw/ 作为默认命名空间,而select 属性中的路径引用空命名空间(searchRetrieveResponse 等)。您可能希望在 XSL 文件中声明命名空间 (xmlns:srw="http://www.loc.gov/zing/srw/") 并限定路径中的元素 (srw:searchRetrieveResponse 等)。
  • 我按照@halfbit 的建议添加了命名空间,并更改了我原来的帖子以反映这些变化。结果有所改善,但我仍然没有达到我的预期。也许您还有其他建议?

标签: xml xslt


【解决方案1】:

以下对我有用:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:srw="http://www.loc.gov/zing/srw/" 
    xmlns:sru="http://standaarden.overheid.nl/sru" 
    xmlns:dcterms="http://purl.org/dc/terms/" 
    xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" 
    xmlns:overheidop="http://standaarden.overheid.nl/product/terms/"
    xmlns:overheidvb="http://standaarden.overheid.nl/vb/terms">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <verkeersbesluiten>
      <test>Hello world!</test>
      <numberOfRecords><xsl:value-of select="srw:searchRetrieveResponse/srw:numberOfRecords"/></numberOfRecords>
      <xsl:for-each select="srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/sru:gzd/sru:originalData/overheidop:meta/overheidop:owmskern">
        <besluit>
          <test2>Hello world again!</test2>
          <titel><xsl:value-of select="dcterms:title"/></titel>
          <locatie><xsl:value-of select="dcterms:spatial"/></locatie>
        </besluit>
      </xsl:for-each>
    </verkeersbesluiten>
  </xsl:template>
</xsl:stylesheet>

它与您在

中的最新 XSL 不同
  • sru 命名空间(它没有尾部斜杠 - 每个字符都很重要)
  • 路径中sru:gzd 之前缺少的srw:recordData

顺便说一句:如果 XML 输入的结构允许(每个 record 预期只有一个 owmskern),您可以将 for-each 缩短为

<xsl:for-each select="srw:searchRetrieveResponse//overheidop:owmskern">

这可能会稍微慢一些,但更具可读性,并且 - 正如您所经历的那样 - 编写/维护的错误可能性较小。


不记录:​​在 XSLT 中,有些人宁愿不使用 for-each 来遍历输入 XML,因为这是 XSLT 处理器正在做的事情,而是编写多个更简单、更集中的模板,如下所示:

  <!-- only traverse, do not copy anything by default -->
  <xsl:template match="@*|node()">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:template>

  <xsl:template match="srw:searchRetrieveResponse">
    <verkeersbesluiten>
      <test>Hello world!</test>
      <numberOfRecords><xsl:value-of select="srw:numberOfRecords"/></numberOfRecords>
      <xsl:apply-templates/>
    </verkeersbesluiten>
  </xsl:template>

  <xsl:template match="overheidop:owmskern">
    <besluit>
      <test2>Hello world again!</test2>
      <titel><xsl:value-of select="dcterms:title"/></titel>
      <locatie><xsl:value-of select="dcterms:spatial"/></locatie>
    </besluit>
  </xsl:template>

【讨论】:

  • 这太棒了!非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 2015-06-25
  • 1970-01-01
  • 2016-09-24
相关资源
最近更新 更多