我正在將 XML 匯入 Access 資料庫。在轉換程序中,資料之間的所有關系都將丟失。使用 XSLT,我通過子節點永久保留 ID。使用這個,Id父元素被添加到子節點的位置:
<xsl:template match="*[*[not(*)] and ancestor::*[Id]]">
<xsl:copy>
<xsl:apply-templates select="ancestor::*[Id]/Id | *"/>
</xsl:copy>
</xsl:template>
我在使用這種方法時遇到的問題是父節點之外還有其他元素也有Id元素或它的變體,例如AccountId或類似的東西。當我嘗試在上面的代碼之外使用它時,Id在以前的節點中會丟失一些實體。
<xsl:template match="*[*[not(*)] and ancestor::*[AccountId]]">
<xsl:copy>
<xsl:apply-templates select="ancestor::*[AccountId]/AccountId | *"/>
</xsl:copy>
</xsl:template>
我很抱歉,因為我不知道在這里使用合適的語言,因為我不太了解 XSLT/XML……但我想要完成的是將模板應用程式的重點縮小到節點在檔案節點(基本元素節點?)下方,以便我可以在更細粒度的級別應用模板。或者,當存在多個不一定相關的 ID 實體時(例如,下面的示例與Link,Alice和Balance節點),找到某種方法使 ID 永久化。請注意,在第一個輸出中, 將Id一直延續到子節點。
這是一個例子。
XML:
<Response>
<Alices>
<Alice>
<Id>12345</Id>
<Bobbers>
<Name>John Doe</Name>
<Bobs>
<Bob>
<Organization>
<Name>John Doe</Name>
<ABB>987654</ABB>
<ContactDetails>
<Adds>
<Add>
<Type>Postal</Type>
<Line1>PO BOX 12345</Line1>
<Suburb>Doeville</Suburb>
<State>ENE</State>
<PostCode>1111</PostCode>
<Country>GB</Country>
<Preferred>false</Preferred>
</Add>
<Add>
<Type>Street</Type>
<Line1>123 Anywhere</Line1>
<Suburb>Doeville</Suburb>
<State>ENE</State>
<PostCode>1111</PostCode>
<Country>GB</Country>
<Preferred>true</Preferred>
</Add>
</Adds>
<PNs>
<PN>
<Type>Mobile</Type>
<Number>11111111</Number>
<Preferred>true</Preferred>
</PN>
</PNs>
<EMs>
<EM>
<Type>Personal</Type>
<Add>[email protected]</Add>
<Preferred>false</Preferred>
</EM>
</EMs>
<PreferredContactMethod>Email</PreferredContactMethod>
</ContactDetails>
<Contacts>
<Contact>
<LastName>Doe</LastName>
<FirstName>John</FirstName>
</Contact>
</Contacts>
</Organization>
</Bob>
</Bobs>
</Bobbers>
<Jons>
<Jon>
<Id>012991</Id>
<PrimaryJon>true</PrimaryJon>
<StartDate>1900-01-01</StartDate>
</Jon>
</Jons>
</Alice>
<Movements>
<Movement>
<AccountId>J54321</AccountId>
<InvestmentCode>ABI</InvestmentCode>
<Exchange>BRU</Exchange>
<Id>YabbaDabba</Id>
<Links>
<Link>
<Id>YabbaDabbaDoo</Id>
<Type>Stone</Type>
</Link>
</Links>
</Movement>
</Movements>
<Balances>
<Balance>
<AccountId>J54321</AccountId>
<Value>123456</Value>
<Investments>
<Investment>
<Code>JJJ</Code>
<UnitBalance>
<Total>112.000000</Total>
</UnitBalance>
</Investment>
</Investments>
</Balance>
</Balances>
</Alices>
</Response>
使用這個 XSLT,沒有 AcctId 模板。注意我正在將Link節點中的元素名稱從IdtoLinkId和它的父元素Id更改TransactionId為to以區分兩者。
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Response/Alices/Movements/Movement/Id">
<TransactionID>
<xsl:apply-templates select="@* | node()"/>
</TransactionID>
</xsl:template>
<xsl:template match="@TransactionID">
<xsl:attribute name="TransactionID">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="Response/Alices/Movements/Movement/Links/Link/Id">
<LinkedTransactionID>
<xsl:apply-templates select="@* | node()"/>
</LinkedTransactionID>
</xsl:template>
<xsl:template match="@LinkedTransactionID">
<xsl:attribute name="LinkedTransactionID">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="*[*[not(*)] and ancestor::*[Id]]">
<xsl:copy>
<xsl:apply-templates select="ancestor::*[Id]/Id | *"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
產生這個。Id元素從Alice節點一直延續到其子節點。同樣在link節點中,TransactionId也從其父級向下推。XSLT 將此名稱TransactionId從更改Id為TransactionId。
<Response>
<Alices>
<Alice>
<Id>12345</Id>
<Bobbers>
<Id>12345</Id>
<Name>John Doe</Name>
<Bobs>
<Bob>
<Organization>
<Id>12345</Id>
<Name>John Doe</Name>
<ABB>987654</ABB>
<ContactDetails>
<Id>12345</Id>
<Adds>
<Add>
<Id>12345</Id>
<Type>Postal</Type>
<Line1>PO BOX 12345</Line1>
<Suburb>Doeville</Suburb>
<State>ENE</State>
<PostCode>1111</PostCode>
<Country>GB</Country>
<Preferred>false</Preferred>
</Add>
<Add>
<Id>12345</Id>
<Type>Street</Type>
<Line1>123 Anywhere</Line1>
<Suburb>Doeville</Suburb>
<State>ENE</State>
<PostCode>1111</PostCode>
<Country>GB</Country>
<Preferred>true</Preferred>
</Add>
</Adds>
<PNs>
<PN>
<Id>12345</Id>
<Type>Mobile</Type>
<Number>11111111</Number>
<Preferred>true</Preferred>
</PN>
</PNs>
<EMs>
<EM>
<Id>12345</Id>
<Type>Personal</Type>
<Add>[email protected]</Add>
<Preferred>false</Preferred>
</EM>
</EMs>
<PreferredContactMethod>Email</PreferredContactMethod>
</ContactDetails>
<Contacts>
<Contact>
<Id>12345</Id>
<LastName>Doe</LastName>
<FirstName>John</FirstName>
</Contact>
</Contacts>
</Organization>
</Bob>
</Bobs>
</Bobbers>
<Jons>
<Jon>
<Id>12345</Id>
<Id>012991</Id>
<PrimaryJon>true</PrimaryJon>
<StartDate>1900-01-01</StartDate>
</Jon>
</Jons>
</Alice>
<Movements>
<Movement>
<AccountId>J54321</AccountId>
<InvestmentCode>ABI</InvestmentCode>
<Exchange>BRU</Exchange>
<TransactionID>YabbaDabba</TransactionID>
<Links>
<Link>
<TransactionID>YabbaDabba</TransactionID>
<LinkedTransactionID>YabbaDabbaDoo</LinkedTransactionID>
<Type>Stone</Type>
</Link>
</Links>
</Movement>
</Movements>
<Balances>
<Balance>
<AccountId>J54321</AccountId>
<Value>123456</Value>
<Investments>
<Investment>
<Code>JJJ</Code>
<UnitBalance>
<Total>112.000000</Total>
</UnitBalance>
</Investment>
</Investments>
</Balance>
</Balances>
</Alices>
</Response>
強調這一部分,特別是我想看到的:
<Link>
<TransactionID>YabbaDabba</TransactionID>
<LinkedTransactionID>YabbaDabbaDoo</LinkedTransactionID>
<Type>Stone</Type>
</Link>
但是,如果我將它添加到 XSLT 以AccountId將Balance節點中的Investment節點永久化,則Link節點 ID 會更改。相關部分低于完整輸出。
<xsl:template match="*[*[not(*)] and ancestor::*[AccountId]]">
<xsl:copy>
<xsl:apply-templates select="ancestor::*[AccountId]/AccountId | *"/>
</xsl:copy>
</xsl:template>
Yields this, where the link node loses its parent's ID:
<Response>
<Alices>
<Alice>
<Id>12345</Id>
<Bobbers>
<Id>12345</Id>
<Name>John Doe</Name>
<Bobs>
<Bob>
<Organization>
<Id>12345</Id>
<Name>John Doe</Name>
<ABB>987654</ABB>
<ContactDetails>
<Id>12345</Id>
<Adds>
<Add>
<Id>12345</Id>
<Type>Postal</Type>
<Line1>PO BOX 12345</Line1>
<Suburb>Doeville</Suburb>
<State>ENE</State>
<PostCode>1111</PostCode>
<Country>GB</Country>
<Preferred>false</Preferred>
</Add>
<Add>
<Id>12345</Id>
<Type>Street</Type>
<Line1>123 Anywhere</Line1>
<Suburb>Doeville</Suburb>
<State>ENE</State>
<PostCode>1111</PostCode>
<Country>GB</Country>
<Preferred>true</Preferred>
</Add>
</Adds>
<PNs>
<PN>
<Id>12345</Id>
<Type>Mobile</Type>
<Number>11111111</Number>
<Preferred>true</Preferred>
</PN>
</PNs>
<EMs>
<EM>
<Id>12345</Id>
<Type>Personal</Type>
<Add>[email protected]</Add>
<Preferred>false</Preferred>
</EM>
</EMs>
<PreferredContactMethod>Email</PreferredContactMethod>
</ContactDetails>
<Contacts>
<Contact>
<Id>12345</Id>
<LastName>Doe</LastName>
<FirstName>John</FirstName>
</Contact>
</Contacts>
</Organization>
</Bob>
</Bobs>
</Bobbers>
<Jons>
<Jon>
<Id>12345</Id>
<Id>012991</Id>
<PrimaryJon>true</PrimaryJon>
<StartDate>1900-01-01</StartDate>
</Jon>
</Jons>
</Alice>
<Movements>
<Movement>
<AccountId>J54321</AccountId>
<InvestmentCode>ABI</InvestmentCode>
<Exchange>BRU</Exchange>
<TransactionID>YabbaDabba</TransactionID>
<Links>
<Link>
<AccountId>J54321</AccountId>
<LinkedTransactionID>YabbaDabbaDoo</LinkedTransactionID>
<Type>Stone</Type>
</Link>
</Links>
</Movement>
</Movements>
<Balances>
<Balance>
<AccountId>J54321</AccountId>
<Value>123456</Value>
<Investments>
<Investment>
<AccountId>J54321</AccountId>
<Code>JJJ</Code>
<UnitBalance>
<AccountId>J54321</AccountId>
<Total>112.000000</Total>
</UnitBalance>
</Investment>
</Investments>
</Balance>
</Balances>
</Alices>
</Response>
Emphasis on these nodes:
<Link>
<AccountId>J54321</AccountId>
<LinkedTransactionID>YabbaDabbaDoo</LinkedTransactionID>
<Type>Stone</Type>
</Link>
and this section is now showing the parent's ID, as I wanted.
<Investment>
<AccountId>J54321</AccountId>
<Code>JJJ</Code>
<UnitBalance>
<AccountId>J54321</AccountId>
<Total>112.000000</Total>
</UnitBalance>
</Investment>
I believe in this situation the issue is that Movement node also has AccountId and some child nodes have Id elements, both affected by the XSLT. So if I need to perpetuate IDs to child nodes from the parent nodes when there are multiple IDs that don't necessarily relate, how do I write the XSLT so that there is no conflict between the templates I'm trying to apply to the same node?
uj5u.com熱心網友回復:
也許限制第二個模板的應用,例如
<xsl:template match="*[*[not(*)] and not(Id) and ancestor::*[AccountId]]">
僅在元素沒有Id子元素時才使用,就像那些Link元素一樣。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/363088.html
