使用 XSLT 将 XML 中所有子节点的密钥添加到 MS Access 传输
Use XSLT to add key to all child nodes in XML to MS Access transfer
我正在尝试使用 XSLT 向所有子节点添加一个键,以便在 XML 导入 MS Access 期间创建的表在所有创建的表中都有一个适当的标识符。我使用了一些我发现的示例将一些 XSLT 拼凑在一起,但我并不从根本上理解它是如何工作的,以至于我无法对其进行故障排除。我可以在 Add
节点中获取 Id
占位符,但值为空。有没有办法以编程方式将 Id
键添加到所有子节点,而无需单独编码每个子节点?如果没有,我该如何编辑 XSLT 以确保 Id
字段通过?
使事情复杂化的是,Add
元素始终在 ContactDetails
之下,但 ContactDetails
相对于 Id
元素在节点方面有所不同。例如,它可能有 4-7 个节点深。
样本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>j.doe@anywhere.com</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>
</Alices>
</Response>
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<dataroot>
<xsl:apply-templates select="@*|node()"/>
</dataroot>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Adds">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="Add">
<Add>
<Id><xsl:value-of select="../../Id"/></Id>
<xsl:apply-templates select="@*|node()"/>
</Add>
</xsl:template>
</xsl:stylesheet>
这就是我想要的:
<Response>
<Alices>
<Alice>
<Id>12345</Id>
<Bobbers>
<Name>John Doe</Name>
<Bobs>
<Bob>
<Organization>
<Id>12345</Id>
<Name>John Doe</Name>
<ABB>987654</ABB>
<ContactDetails>
<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>j.doe@anywhere.com</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>012991</Id>
<PrimaryJon>true</PrimaryJon>
<StartDate>1900-01-01</StartDate>
</Jon>
</Jons>
</Alice>
</Alices>
</Response>
尝试按照
<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="*[*[not(*)] and ancestor::*[Id]]">
<xsl:copy>
<xsl:apply-templates select="ancestor::*[Id]/Id | *"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我正在尝试使用 XSLT 向所有子节点添加一个键,以便在 XML 导入 MS Access 期间创建的表在所有创建的表中都有一个适当的标识符。我使用了一些我发现的示例将一些 XSLT 拼凑在一起,但我并不从根本上理解它是如何工作的,以至于我无法对其进行故障排除。我可以在 Add
节点中获取 Id
占位符,但值为空。有没有办法以编程方式将 Id
键添加到所有子节点,而无需单独编码每个子节点?如果没有,我该如何编辑 XSLT 以确保 Id
字段通过?
使事情复杂化的是,Add
元素始终在 ContactDetails
之下,但 ContactDetails
相对于 Id
元素在节点方面有所不同。例如,它可能有 4-7 个节点深。
样本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>j.doe@anywhere.com</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>
</Alices>
</Response>
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<dataroot>
<xsl:apply-templates select="@*|node()"/>
</dataroot>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Adds">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="Add">
<Add>
<Id><xsl:value-of select="../../Id"/></Id>
<xsl:apply-templates select="@*|node()"/>
</Add>
</xsl:template>
</xsl:stylesheet>
这就是我想要的:
<Response>
<Alices>
<Alice>
<Id>12345</Id>
<Bobbers>
<Name>John Doe</Name>
<Bobs>
<Bob>
<Organization>
<Id>12345</Id>
<Name>John Doe</Name>
<ABB>987654</ABB>
<ContactDetails>
<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>j.doe@anywhere.com</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>012991</Id>
<PrimaryJon>true</PrimaryJon>
<StartDate>1900-01-01</StartDate>
</Jon>
</Jons>
</Alice>
</Alices>
</Response>
尝试按照
<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="*[*[not(*)] and ancestor::*[Id]]">
<xsl:copy>
<xsl:apply-templates select="ancestor::*[Id]/Id | *"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>