【问题标题】:使用 XSLT 查找 XML
【发布时间】:2022-01-16 07:39:16
【问题描述】:

我在使用带有 XSLT 的查找 XML 时遇到了我的代码

我的 XML 是这样的:

<?xml version="1.0"?>
<Invoices>
   <invoice>
      <customer>
         <name>Juan tamban</name>
      </customer>
      <details>
         <VAT>0001</VAT>
         <items>
            <item code="I01" name="Item1" />
            <item code="I02" name="Item2" />
         </items>
      </details>
   </invoice>
   <invoice>
      <customer>
         <name>Johny Cash</name>
      </customer>
      <details>
         <VAT>0002</VAT>
         <items>
            <item code="I03" name="Item3" />
            <item code="I04" name="Item4" />
         </items>
      </details>
   </invoice>
</Invoices>

我当前的 XSLT 看起来像这样:

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

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:variable name="lookupdoc" select="document('Lookup.xml')/VATS/VAT"/>

   <xsl:key name="VAT-by-id" match="VAT" use="@id"/>

   <xsl:template name="getCode">
      <xsl:param name="VATNumber" />
      <xsl:variable name="VATId" select="$VATNumber/."/>
      <xsl:for-each select="$lookupdoc">
         <xsl:value-of select="key('VAT-by-id', $VATId/VAT)/code"/>
      </xsl:for-each>
   </xsl:template>

   <xsl:template match="items/item">
      <Item>
         <ItemCOde>
            <xsl:value-of select="@code"/>
         </ItemCOde>
         <ItemName>
            <xsl:value-of select="@name"/>
         </ItemName>
      </Item>
   </xsl:template>

   <xsl:template match="invoice">
      <xsl:variable name="VAT">
         <xsl:call-template name="getCode">
            <xsl:with-param name="VATNumber" select="details/VAT" />
         </xsl:call-template>
      </xsl:variable>

      <InvoiceDetails>
         <CustomerName>
            <xsl:value-of select="customer/name"/>
         </CustomerName>
         <VATCode>
            <xsl:value-of select="$VAT" />
         </VATCode>
         <xsl:apply-templates select="details/items/item" />
      </InvoiceDetails>
   </xsl:template>

   <xsl:template match="Invoices">
      <Invoices>
         <xsl:apply-templates select ="invoice"/>
      </Invoices>
   </xsl:template>
</xsl:stylesheet>

我的查找 XML 是这样的:

<?xml version="1.0" encoding="utf-8"?>
<VATS>
   <VAT id="0001" code="0001-000101/08-12-2021"/>
   <VAT id="0002" code="0002-000102/09-12-2021"/>
   <VAT id="0003" code="0003-000103/10-12-2021"/>
   <VAT id="0004" code="0004-000104/11-12-2021"/>
</VATS>

我的结果是这样的,你可以看到 VATCode 标签没有填写:

<?xml version="1.0" encoding="utf-8"?>
<Invoices>
  <InvoiceDetails>
    <CustomerName>Juan tamban</CustomerName>
    <VATCode></VATCode>
    <Item>
      <ItemCOde>I01</ItemCOde>
      <ItemName>Item1</ItemName>
    </Item>
    <Item>
      <ItemCOde>I02</ItemCOde>
      <ItemName>Item2</ItemName>
    </Item>
  </InvoiceDetails>
  <InvoiceDetails>
    <CustomerName>Johny Cash</CustomerName>
    <VATCode></VATCode>
    <Item>
      <ItemCOde>I03</ItemCOde>
      <ItemName>Item3</ItemName>
    </Item>
    <Item>
      <ItemCOde>I04</ItemCOde>
      <ItemName>Item4</ItemName>
    </Item>
  </InvoiceDetails>
</Invoices>

谁能告诉我这段代码缺少什么或有什么问题?

感谢您的帮助。

【问题讨论】:

  • 顺便问一下,当lookup.XML不存在时,我能做些什么来防止VS崩溃吗?
  • 崩溃是处理器的“特性”,而不是 XSLT 代码。正确的行为是抛出错误。也许问一个新问题并相应地标记它。

标签: xml xslt xslt-1.0


【解决方案1】:

我认为你在尝试使用钥匙时将自己射中了脚,你只是想要

   <xsl:template name="getCode">
      <xsl:param name="VATNumber" />
      <xsl:for-each select="$lookupdoc">
         <xsl:value-of select="key('VAT-by-id', $VATNumber)/@code"/>
      </xsl:for-each>
   </xsl:template>

我还将&lt;xsl:variable name="lookupdoc" select="document('Lookup.xml')/VATS/VAT"/&gt; 更改为&lt;xsl:variable name="lookupdoc" select="document('Lookup.xml')"/&gt;,因为您只需要并且在使用键时需要文档节点进行上下文切换,因此向下选择没有任何优势。

【讨论】:

  • 改了你的建议后还是一样
  • @zyberjock,对,建议是正确的,但 value-of 的选择也有误,现已修复。
  • 顺便问一下,当lookup.XML不存在时,我能做些什么来防止VS崩溃吗?
【解决方案2】:

如果您更改此代码,您的代码将起作用:

<xsl:variable name="lookupdoc" select="document('Lookup.xml')/VATS/VAT"/>

到:

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

还有这个:

   <xsl:template name="getCode">
      <xsl:param name="VATNumber" />
      <xsl:variable name="VATId" select="$VATNumber/."/>
      <xsl:for-each select="$lookupdoc">
         <xsl:value-of select="key('VAT-by-id', $VATId/VAT)/code"/>
      </xsl:for-each>
   </xsl:template>

到:

   <xsl:template name="getCode">
      <xsl:param name="VATNumber" />
      <xsl:for-each select="$lookupdoc">
         <xsl:value-of select="key('VAT-by-id', $VATNumber)/@code"/>
      </xsl:for-each>
   </xsl:template>

当然,您可以将整个内容缩短为:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="lookupdoc" select="document('Lookup.xml')"/>

<xsl:key name="VAT-by-id" match="VAT" use="@id"/>

<xsl:template match="/Invoices">
    <Invoices>
        <xsl:apply-templates select="invoice"/>
    </Invoices>
</xsl:template>

<xsl:template match="invoice">
    <InvoiceDetails>
        <CustomerName>
            <xsl:value-of select="customer/name"/>
        </CustomerName>
         <VATCode>
            <xsl:variable name="VATNumber" select="details/VAT" />
            <xsl:for-each select="$lookupdoc">
                <xsl:value-of select="key('VAT-by-id', $VATNumber)/@code"/>
            </xsl:for-each>
         </VATCode>
        <xsl:apply-templates select="details/items/item" />
    </InvoiceDetails>
</xsl:template>

<xsl:template match="items/item">
    <Item>
        <ItemCOde>
            <xsl:value-of select="@code"/>
         </ItemCOde>
        <ItemName>
            <xsl:value-of select="@name"/>
         </ItemName>
    </Item>
</xsl:template>

</xsl:stylesheet>

附:我相信您使用密钥的决定是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 2015-05-14
    • 2011-06-01
    • 1970-01-01
    相关资源
    最近更新 更多