【问题标题】:XSLT document() not calling specific nodesXSLT document() 不调用特定节点
【发布时间】:2020-04-16 14:39:20
【问题描述】:

我正在尝试在我的 xsl 代码中调用“firstName”节点,但是当我尝试调用“value-of select="firstName”时,它似乎不起作用,并且一旦转换,它不会显示任何内容为它。

我的 xsl 代码是:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:variable name="customers" select="document('customer.xml')/customers"/>

    <xsl:template match="/">
        <xsl:copy>
            <xsl:for-each select="transactions/transaction">
                <xsl:sort select="giftShop"/>
                <xsl:sort select="transaction_date"/>
                Shop: <xsl:value-of select="giftShop"/>
                Date: <xsl:value-of select="transaction_date"/>
                <xsl:for-each select="$customers">
                    <xsl:value-of select="."/>
                </xsl:for-each>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

transactions.xml(第一个 xml 文件):

<?xml version="1.0"?>
<transactions>
    <transaction>
        <transaction_date>01/11/2019</transaction_date>
        <customerID>8BLOJZWL</customerID>
        <giftShop>1</giftShop>
        <transactionID>BjYAtd7lmEOlQUVy</transactionID>
        <value currency="gbp">149.99</value>
    </transaction>
    <transaction>
        <transaction_date>01/11/2019</transaction_date>
        <customerID>DR18OCFI</customerID>
        <giftShop>2</giftShop>
        <transactionID>aQ27lMvfnlzY4mkx</transactionID>
        <value currency="gbp">100.11</value>
    </transaction>
<transaction>

customer.xml(第二个 xml 文件):

<?xml version="1.0"?>
<customers>
    <customer>
        <prefix>Mrs</prefix>
        <lastName>Samantha</lastName>
        <givenName>Smith</givenName>
        <addressID>213456</addressID>
        <customerID>ASJ4OTLG</customerID>
    </customer>
    <customer>
        <prefix>Mr </prefix>
        <lastName>Cameron</lastName>
        <givenName>Wills</givenName>
        <addressID>125907</addressID>
        <customerID>SID8RY23</customerID>
    </customer>
</customers>

预期输出: 如果我的预期输出不是很准确也很抱歉,我对 xml 和 xsl 很陌生

<giftShop>
    <transaction_date>
        <transacation>
            <customer>

我正在尝试调用特定的“客户数据”,但目前它会显示所有数据并在我尝试关闭文件时不断使我的 Notepad++ 崩溃。

非常感谢任何帮助!

【问题讨论】:

  • 发布您正在处理的 XML 输入将极大地帮助我们理解和重现您的问题。
  • 我可以包含它们,但是 xml 文件很大并且加载了数据
  • 输入的一部分就足够了。尝试制作stackoverflow.com/help/minimal-reproducible-example
  • 我已经放入了我的两个 xml 文件,这些文件都大大缩短了,希望能有所帮助!
  • 请同时添加预期的输出。

标签: xml xslt transform document


【解决方案1】:

我猜(!)你想做这样的事情:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:variable name="customers" select="document('retail_customer.xml')/customers"/>

<xsl:template match="/transactions">
    <xsl:for-each select="transaction">
        <xsl:sort select="giftShop"/>
        <xsl:sort select="transaction_date"/>
        <xsl:text>Shop: </xsl:text>
        <xsl:value-of select="giftShop"/>
        <xsl:text>&#10;Date: </xsl:text>
        <xsl:value-of select="transaction_date"/>
        <xsl:variable name="customer" select="$customers/customer[customerID=current()/customerID]"/>
        <xsl:text>&#10;Customer: </xsl:text>
        <xsl:value-of select="$customer/lastName"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="$customer/givenName"/>
        <xsl:text>&#10;&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

当然,这只有在交易在另一个文档中有匹配的客户时才有效。在您的示例中,没有。


P.S. 请注意,&lt;xsl:sort select="transaction_date"/&gt; 在您的情况下将无法正常工作,因为您的日期采用 DD/MM/YYYY(或 MM/DD/YYYY?)格式,并且按字母顺序排序不会产生时间顺序.但这是一个单独的问题(您可以在这里找到答案:https://stackoverflow.com/a/58251767/3016153)。

【讨论】:

  • 在模板之外声明 document() 调用(作为“全局”变量)是否有性能优势,这样每次调用时都不必在文件上创建新句柄模板被调用还是解析器自己优化?
  • @Sebastien 我不知道,为了安全起见,我会更改它。
  • 这非常有帮助,肯定会提供我需要的输出,但是我正在尝试匹配两个文件中的 customerID 并显示每个文件的数据。
  • 恐怕我不明白这是什么意思。
【解决方案2】:

由于您的文档变量已经引用了“客户”

<xsl:variable name="customers" select="document('customer.xml')/customers"/>

当你做你的 for 循环时

<xsl:for-each select="$customers">
  <xsl:value-of select="."/>
</xsl:for-each>

你应该做这样的事情

<xsl:for-each select="$customers/customer">
  <xsl:value-of select="customerID"/> <!-- Or whichever node you want -->
</xsl:for-each>

【讨论】:

  • 这确实工作正常,并获得了我需要的信息,但是当我尝试创建一个 for-each select="transactions/transaction" 时,我将如何从事务 xml 文件中包含节点,它只显示$customers 节点
  • 请发布您的预期输出。 (更新您原来的问题。)
  • 我已经添加了预期的输出,但是我对 xsl 和 xml 很陌生,我应该在前面提到这一点,所以我不太确定我的确切输出应该是什么样子。
猜你喜欢
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多