如何获取当前元素属性

时间:2016-07-02 20:50:12

标签: xml xslt xslt-1.0 msxml

XSL用于对XML进行反规范化,以便导入到平面数据库表中。

对于每个发票,invoiceid列必须包含此发票ID。

但原因不明

    <xsl:value-of select="../../../../../../Invoice/@invoiceId"/>

在arvenumber元素中始终返回第一个发票ID 1605002。所以所有行都有相同的id。 怎么解决?

XML:

<?xml version="1.0" encoding="windows-1257"?>

<Envelope>
  <Body>
    <BuyInvoicesResponse>
      <E_Invoice>
        <Invoice invoiceId='1605002'>
          <InvoiceItem>
            <InvoiceItemGroup>
              <ItemEntry>
                <SellerProductId>YEYLD</SellerProductId>
                <Description>Üldelekter</Description>
                <EAN>23225325</EAN>
                <ItemDetailInfo>
                  <ItemUnit>m2</ItemUnit>
                  <ItemAmount>1.96</ItemAmount>
                  <ItemPrice>1</ItemPrice>
                </ItemDetailInfo>
                <ItemSum>1.96</ItemSum>
                <VAT>
                  <SumBeforeVAT>1.96</SumBeforeVAT>
                  <VATRate>0.00</VATRate>
                  <VATSum>0.00</VATSum>
                </VAT>
                <ItemTotal>1.96</ItemTotal>
              </ItemEntry>
              <ItemEntry>
                <SellerProductId>YKV</SellerProductId>
                <Description>Vesi ja kanalisatsioon</Description>
                <EAN></EAN>
                <ItemDetailInfo>
                  <ItemUnit>m3</ItemUnit>
                  <ItemAmount>4.10</ItemAmount>
                  <ItemPrice>2.07600</ItemPrice>
                </ItemDetailInfo>
                <ItemSum>8.51</ItemSum>
                <VAT>
                  <SumBeforeVAT>8.51</SumBeforeVAT>
                  <VATRate>0.00</VATRate>
                  <VATSum>0.00</VATSum>
                </VAT>
                <ItemTotal>8.51</ItemTotal>
              </ItemEntry>
              <ItemEntry>
                <SellerProductId>YPRYGI</SellerProductId>
                <Description>Prügivedu</Description>
                <EAN></EAN>
                <ItemDetailInfo>
                  <ItemUnit>m2</ItemUnit>
                  <ItemAmount>1.84</ItemAmount>
                  <ItemPrice>1</ItemPrice>
                </ItemDetailInfo>
                <ItemSum>1.84</ItemSum>
                <VAT>
                  <SumBeforeVAT>1.84</SumBeforeVAT>
                  <VATRate>0.00</VATRate>
                  <VATSum>0.00</VATSum>
                </VAT>
                <ItemTotal>1.84</ItemTotal>
              </ItemEntry>
              <ItemEntry>
                <SellerProductId>YSV</SellerProductId>
                <Description>Vee soojendamine</Description>
                <EAN></EAN>
                <ItemDetailInfo>
                  <ItemUnit>m3</ItemUnit>
                  <ItemAmount>1.50</ItemAmount>
                  <ItemPrice>2.10600</ItemPrice>
                </ItemDetailInfo>
                <ItemSum>3.16</ItemSum>
                <VAT>
                  <SumBeforeVAT>3.16</SumBeforeVAT>
                  <VATRate>0.00</VATRate>
                  <VATSum>0.00</VATSum>
                </VAT>
                <ItemTotal>3.16</ItemTotal>
              </ItemEntry>
            </InvoiceItemGroup>
          </InvoiceItem>
        </Invoice>
        <Invoice invoiceId='1605006'>
          <InvoiceItem>
            <InvoiceItemGroup>
              <ItemEntry>
                <SellerProductId>YEYLD</SellerProductId>
                <Description>Üldelekter</Description>
                <EAN>23225325</EAN>
                <ItemDetailInfo>
                  <ItemUnit>m2</ItemUnit>
                  <ItemAmount>2.50</ItemAmount>
                  <ItemPrice>1</ItemPrice>
                </ItemDetailInfo>
                <ItemSum>2.50</ItemSum>
                <VAT>
                  <SumBeforeVAT>2.50</SumBeforeVAT>
                  <VATRate>0.00</VATRate>
                  <VATSum>0.00</VATSum>
                </VAT>
                <ItemTotal>2.50</ItemTotal>
              </ItemEntry>
            </InvoiceItemGroup>
          </InvoiceItem>
        </Invoice>
      </E_Invoice>

    </BuyInvoicesResponse>
  </Body>
</Envelope>

XSL:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes"/>
  <xsl:template match="/">
    <xsl:element name="VFPData">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="/Envelope/Body/BuyInvoicesResponse/E_Invoice/Invoice/InvoiceItem/InvoiceItemGroup/ItemEntry/Accounting/*">
    <xsl:element name="Document-BuyInvoice">
      <xsl:element name="arvenumber">
        <xsl:value-of select="../../../../../../Invoice/@invoiceId"/>
      </xsl:element>
      <xsl:element name="nimetus">
        <xsl:value-of select="../../Description"/>
      </xsl:element>
    </xsl:element>
  </xsl:template>

  <!-- to ommit nodes data -->
  <xsl:template match="text()">
  </xsl:template>

  <!-- to work over every node -->
  <xsl:template match="*">
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

MSXML解析器用于转换

1 个答案:

答案 0 :(得分:1)

如果您希望InvoiceID位于最近的封闭Invoice元素上,请尝试编写/* Typedefs representing our rules for sentence generations */ typedef std::vector<std::string> Rule; typedef std::vector<Rule> RuleCollection; typedef std::map<std::string, RuleCollection> Grammar; /* Forward declarations */ std::vector<std::string> split(std::string); Grammar read_grammar(std::istream &in) { Grammar grammar; std::string line; while (getline(in, line)) { std::vector<std::string> entry = split(line); if (!entry.empty()) { // Use the category to store the associated rule // Why is this an error? // grammar[entry[0]].push_back(Rule(entry.begin() + 1, entry.end())); } } return grammar; } 而不是ancestor::Invoice[1]/@invoiceId

你展示的XPath在XML元素树上费力地爬上去,直到它到达E_Invooice元素(那是六倍../../../../../../Invoice/@invoiceId),然后下降到名为Invoice的那个元素的子元素及其invoiceId属性。由于有许多Invoice元素是E_Invoice的子元素,因此显示的XPath表达式的值是一组属性节点。由于..只需要一个值,因此它会占用第一个值并将其余值抛弃。

避免这个问题的关键是避免爬过你想要的发票元素,因为那时你必须向后爬,你怎么知道你真正想要的许多发票元素中的哪一个?祖先轴允许您不再进入Invoice元素,从而避免了任何关于您想要的Invoice元素的歧义:您想要的是当前节点的祖先。