如果只有一个或零个(空)元素,则在元素之前添加 XML 处理指令
Adding an XML Processing Instruction just before the element if there are only one or zero (empty) elements
我有以下 xml,
<Standards xmlns="http://ws.wso2.org/dataservice">
<Standard>
<ProductID>200057</ProductID>
<Prefix>ISO</Prefix>
<SNumber>1001</SNumber>
<Year>1986</Year>
<Designation>ISO 1001:1986</Designation>
<Publisher>ISO</Publisher>
<ProductDescriptions>
<ProductDescription>
<LanguageCode>en</LanguageCode>
<DescriptionID>372980</DescriptionID>
</ProductDescription>
<ProductDescription>
<LanguageCode>fr</LanguageCode>
<DescriptionID>1878599</DescriptionID>
</ProductDescription>
</ProductDescriptions>
<IndustryCodes/>
<ProductAttributes/>
<ProductReconfirmationNotices/>
</Standard>
</Standards>
并想将其转换成下面的格式。
<Standards xmlns="http://ws.wso2.org/dataservice">
<Standard>
<ProductID>200057</ProductID>
<Prefix>ISO</Prefix>
<SNumber>1001</SNumber>
<Year>1986</Year>
<Designation>ISO 1001:1986</Designation>
<Publisher>ISO</Publisher>
<ProductDescriptions>
<LanguageCode>en</LanguageCode>
<DescriptionID>372980</DescriptionID>
</ProductDescriptions>
<ProductDescriptions>
<LanguageCode>fr</LanguageCode>
<DescriptionID>1878599</DescriptionID>
</ProductDescriptions>
<IndustryCodes/>
<ProductAttributes/>
</Standard>
</Standards>
我能够使用以下 xslt 模板匹配项来完成此操作。所做的是将所有具有 ProductDescription 或 IndustryCode 或 ProductAttribute 或 SaleItem 或 SaleItemAttribute 等的元素作为子元素,并将其替换为源 xml.
中的父元素名称
<xsl:template
match="*[x:ProductDescription]|*[x:IndustryCode]|*[x:ProductAttribute]|*[x:SaleItem]|*[x:SaleItemAttribute]|*[x:SaleItemfile]|*[x:SaleItemPrice]">
<xsl:apply-templates />
</xsl:template>
<!-- Replace "item" with its parent in source XML -->
<xsl:template
match="x:ProductDescription|x:IndustryCode|x:ProductAttribute|x:SaleItem|x:SaleItemAttribute|x:SaleItemfile|x:SaleItemPrice">
<xsl:element name="{name(..)}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
但现在我需要添加一个 XML 处理指令,结果 xml 应该是这样的。如果这里有很多这样的元素,例如 ProductDescription,我只需要在这些元素第一次出现之前添加 PI。如果没有元素(即空元素),例如 IndustryCodes,甚至只有一个元素,例如 Standard,我也需要添加相同的 PI。
<Standards xmlns="http://ws.wso2.org/dataservice">
<?xml-multiple ?>
<Standard>
<ProductID>200057</ProductID>
<Prefix>ISO</Prefix>
<SNumber>1001</SNumber>
<Year>1986</Year>
<Designation>ISO 1001:1986</Designation>
<Publisher>ISO</Publisher>
<?xml-multiple ?>
<ProductDescriptions>
<LanguageCode>en</LanguageCode>
<DescriptionID>372980</DescriptionID>
</ProductDescriptions>
<ProductDescriptions>
<LanguageCode>fr</LanguageCode>
<DescriptionID>1878599</DescriptionID>
</ProductDescriptions>
<?xml-multiple ?>
<IndustryCodes/>
<?xml-multiple ?>
<ProductAttributes/>
</Standard>
</Standards>
XML可以在xslt中添加如下处理指令(PI)
<xsl:processing-instruction name="xml-multiple"/>
我怎样才能改变上面的模板来完成这件事。感谢任何帮助。
对于你现有的模板,替换了parent元素,你可以直接在指令中添加
<xsl:template
match="*[x:ProductDescription]|*[x:IndustryCode]|*[x:ProductAttribute]|*[x:SaleItem]|*[x:SaleItemAttribute]|*[x:SaleItemfile]|*[x:SaleItemPrice]">
<xsl:processing-instruction name="xml-multiple"/>
<xsl:apply-templates />
</xsl:template>
然后您将需要一个单独的模板来处理空元素
<xsl:template
match="x:ProductDescriptions|x:IndustryCodes|x:ProductAttributes|x:SaleItems|x:SaleItemAttributes|x:SaleItemfiles|x:SaleItemPrices">
<xsl:processing-instruction name="xml-multiple"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
请注意,您无需检查它们是否具有 child 个元素。因为当他们有 children 时另一个模板匹配他们,因为它具有更高的优先级(因为它有条件检查)将被使用。
您也可以将 Standard
元素添加到此列表中。
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:x="http://ws.wso2.org/dataservice">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="x:Standard|x:ProductDescriptions|x:IndustryCodes|x:ProductAttributes|x:SaleItems|x:SaleItemAttributes|x:SaleItemfiles|x:SaleItemPrices">
<xsl:processing-instruction name="xml-multiple"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="*[x:ProductDescription]|*[x:IndustryCode]|*[x:ProductAttribute]|*[x:SaleItem]|*[x:SaleItemAttribute]|*[x:SaleItemfile]|*[x:SaleItemPrice]" >
<xsl:processing-instruction name="xml-multiple"/>
<xsl:apply-templates />
</xsl:template>
<!-- Replace "item" with its parent in source XML -->
<xsl:template
match="x:ProductDescription|x:IndustryCode|x:ProductAttribute|x:SaleItem|x:SaleItemAttribute|x:SaleItemfile|x:SaleItemPrice">
<xsl:element name="{name(..)}" namespace="http://ws.wso2.org/dataservice">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我有以下 xml,
<Standards xmlns="http://ws.wso2.org/dataservice">
<Standard>
<ProductID>200057</ProductID>
<Prefix>ISO</Prefix>
<SNumber>1001</SNumber>
<Year>1986</Year>
<Designation>ISO 1001:1986</Designation>
<Publisher>ISO</Publisher>
<ProductDescriptions>
<ProductDescription>
<LanguageCode>en</LanguageCode>
<DescriptionID>372980</DescriptionID>
</ProductDescription>
<ProductDescription>
<LanguageCode>fr</LanguageCode>
<DescriptionID>1878599</DescriptionID>
</ProductDescription>
</ProductDescriptions>
<IndustryCodes/>
<ProductAttributes/>
<ProductReconfirmationNotices/>
</Standard>
</Standards>
并想将其转换成下面的格式。
<Standards xmlns="http://ws.wso2.org/dataservice">
<Standard>
<ProductID>200057</ProductID>
<Prefix>ISO</Prefix>
<SNumber>1001</SNumber>
<Year>1986</Year>
<Designation>ISO 1001:1986</Designation>
<Publisher>ISO</Publisher>
<ProductDescriptions>
<LanguageCode>en</LanguageCode>
<DescriptionID>372980</DescriptionID>
</ProductDescriptions>
<ProductDescriptions>
<LanguageCode>fr</LanguageCode>
<DescriptionID>1878599</DescriptionID>
</ProductDescriptions>
<IndustryCodes/>
<ProductAttributes/>
</Standard>
</Standards>
我能够使用以下 xslt 模板匹配项来完成此操作。所做的是将所有具有 ProductDescription 或 IndustryCode 或 ProductAttribute 或 SaleItem 或 SaleItemAttribute 等的元素作为子元素,并将其替换为源 xml.
中的父元素名称 <xsl:template
match="*[x:ProductDescription]|*[x:IndustryCode]|*[x:ProductAttribute]|*[x:SaleItem]|*[x:SaleItemAttribute]|*[x:SaleItemfile]|*[x:SaleItemPrice]">
<xsl:apply-templates />
</xsl:template>
<!-- Replace "item" with its parent in source XML -->
<xsl:template
match="x:ProductDescription|x:IndustryCode|x:ProductAttribute|x:SaleItem|x:SaleItemAttribute|x:SaleItemfile|x:SaleItemPrice">
<xsl:element name="{name(..)}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
但现在我需要添加一个 XML 处理指令,结果 xml 应该是这样的。如果这里有很多这样的元素,例如 ProductDescription,我只需要在这些元素第一次出现之前添加 PI。如果没有元素(即空元素),例如 IndustryCodes,甚至只有一个元素,例如 Standard,我也需要添加相同的 PI。
<Standards xmlns="http://ws.wso2.org/dataservice">
<?xml-multiple ?>
<Standard>
<ProductID>200057</ProductID>
<Prefix>ISO</Prefix>
<SNumber>1001</SNumber>
<Year>1986</Year>
<Designation>ISO 1001:1986</Designation>
<Publisher>ISO</Publisher>
<?xml-multiple ?>
<ProductDescriptions>
<LanguageCode>en</LanguageCode>
<DescriptionID>372980</DescriptionID>
</ProductDescriptions>
<ProductDescriptions>
<LanguageCode>fr</LanguageCode>
<DescriptionID>1878599</DescriptionID>
</ProductDescriptions>
<?xml-multiple ?>
<IndustryCodes/>
<?xml-multiple ?>
<ProductAttributes/>
</Standard>
</Standards>
XML可以在xslt中添加如下处理指令(PI)
<xsl:processing-instruction name="xml-multiple"/>
我怎样才能改变上面的模板来完成这件事。感谢任何帮助。
对于你现有的模板,替换了parent元素,你可以直接在指令中添加
<xsl:template
match="*[x:ProductDescription]|*[x:IndustryCode]|*[x:ProductAttribute]|*[x:SaleItem]|*[x:SaleItemAttribute]|*[x:SaleItemfile]|*[x:SaleItemPrice]">
<xsl:processing-instruction name="xml-multiple"/>
<xsl:apply-templates />
</xsl:template>
然后您将需要一个单独的模板来处理空元素
<xsl:template
match="x:ProductDescriptions|x:IndustryCodes|x:ProductAttributes|x:SaleItems|x:SaleItemAttributes|x:SaleItemfiles|x:SaleItemPrices">
<xsl:processing-instruction name="xml-multiple"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
请注意,您无需检查它们是否具有 child 个元素。因为当他们有 children 时另一个模板匹配他们,因为它具有更高的优先级(因为它有条件检查)将被使用。
您也可以将 Standard
元素添加到此列表中。
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:x="http://ws.wso2.org/dataservice">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="x:Standard|x:ProductDescriptions|x:IndustryCodes|x:ProductAttributes|x:SaleItems|x:SaleItemAttributes|x:SaleItemfiles|x:SaleItemPrices">
<xsl:processing-instruction name="xml-multiple"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="*[x:ProductDescription]|*[x:IndustryCode]|*[x:ProductAttribute]|*[x:SaleItem]|*[x:SaleItemAttribute]|*[x:SaleItemfile]|*[x:SaleItemPrice]" >
<xsl:processing-instruction name="xml-multiple"/>
<xsl:apply-templates />
</xsl:template>
<!-- Replace "item" with its parent in source XML -->
<xsl:template
match="x:ProductDescription|x:IndustryCode|x:ProductAttribute|x:SaleItem|x:SaleItemAttribute|x:SaleItemfile|x:SaleItemPrice">
<xsl:element name="{name(..)}" namespace="http://ws.wso2.org/dataservice">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:stylesheet>