感谢各位成员的慷慨反馈,我在XML to XML项目上取得了一些重大进展。
那就是说,我在项目的最终版本中遇到了两个问题,并希望更好地理解为什么会出现这些问题。
首先,我需要创建一个由多个值组成的连接元素值。我使用以下代码工作:
<xsl:template match="estimate/JobParts/JobPart/description">
<description>
<xsl:value-of select="concat(estimate/description,'_QTY-',estimate/JobParts/JobPart/qtyOrdered,'_',estimate/JobParts/JobPart/itemTemplate)"/>
</description>
</xsl:template>
查找estimate/JobParts/JobPart/description
的所有匹配项,但在所有情况下,在替换描述值时仅使用第一个匹配的同级元素值。
这是否需要使用密钥来管理迭代?如果是这样,我该如何创建一个?是否有另一种使用apply-template处理此方法的方法,以便可以自动处理迭代管理,如果是,那将如何构建?
我遇到的另一个问题是我需要手动将CDATA标识添加到元素中,并且无法将该元素添加到cdata-section-elements中的列表中,因为在文档中更深层嵌套了另一个具有相同名称的元素不需要CDATA指定的结构。
以下是我尝试用来手动添加CDATA标志的代码:
<xsl:template match="estimate/description">
<description>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="estimate/description"/>
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</description>
</xsl:template>
有趣的是,这对目标描述元素没有任何影响。
如果有人有一些想法,为什么这些变换中的任何一个(或两个)都无法正常工作,我渴望学习和理解。
提前为代码攻击道歉但这里是最初的XML:
<?xml version="1.0"?>
<PODOrderSheet_Main>
<estimate>
<customer>LINFNC</customer>
<newJob>Y</newJob>
<incrementJobVersion>Y</incrementJobVersion>
<description><![CDATA[409511]]></description>
<billPartsTogether>1</billPartsTogether>
<dateSetup><![CDATA[4/24/2013]]></dateSetup>
<promiseDate><![CDATA[4/24/2013]]></promiseDate>
<scheduledShipDate><![CDATA[4/24/2013]]></scheduledShipDate>
<adminStatus>O</adminStatus>
<shipVia>1</shipVia>
<jobType>5020</jobType>
<poNum><![CDATA[409511]]></poNum>
<itemTemplate><![CDATA[33503MN_0212]]></itemTemplate>
<JobParts>
<JobPart>
<jobPart>01</jobPart>
<contactNum/>
<description><![CDATA[REPLACEMENT OF LIFE INSURANCE OR ANNUITIES MINNESOTA]]></description>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[3]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[33503MN_0212]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>01</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
</JobParts>
</estimate>
<estimate>
<customer>LINFNC</customer>
<newJob>Y</newJob>
<incrementJobVersion>Y</incrementJobVersion>
<description><![CDATA[409511]]></description>
<billPartsTogether>1</billPartsTogether>
<dateSetup><![CDATA[4/24/2013]]></dateSetup>
<promiseDate><![CDATA[4/24/2013]]></promiseDate>
<scheduledShipDate><![CDATA[4/24/2013]]></scheduledShipDate>
<adminStatus>O</adminStatus>
<shipVia>1</shipVia>
<jobType>5020</jobType>
<poNum><![CDATA[409511]]></poNum>
<itemTemplate><![CDATA[AL-FSC-FST068_Z08]]></itemTemplate>
<JobParts>
<JobPart>
<jobPart>01</jobPart>
<contactNum/>
<description><![CDATA[AMERICAN LEGACY III C SHARE FACT SHEET ]]></description>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[1]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[AL-FSC-FST068_Z08]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>01</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
</JobParts>
</estimate>
<estimate>
<customer>LINFNC</customer>
<newJob>Y</newJob>
<incrementJobVersion>Y</incrementJobVersion>
<description><![CDATA[409511]]></description>
<billPartsTogether>1</billPartsTogether>
<dateSetup><![CDATA[4/24/2013]]></dateSetup>
<promiseDate><![CDATA[4/24/2013]]></promiseDate>
<scheduledShipDate><![CDATA[4/24/2013]]></scheduledShipDate>
<adminStatus>O</adminStatus>
<shipVia>1</shipVia>
<jobType>5020</jobType>
<poNum><![CDATA[409511]]></poNum>
<itemTemplate><![CDATA[AN06819-AL3C_1012]]></itemTemplate>
<JobParts>
<JobPart>
<jobPart>01</jobPart>
<contactNum/>
<description><![CDATA[AMERICAN LEGACY III C SHARE APPLICATION SUPPLEMENT - MULTI-STATE]]></description>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[1]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[AN06819-AL3C_1012]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>01</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
</JobParts>
</estimate>
</PODOrderSheet_Main>
这是所需的输出:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE estimate>
<estimate>
<customer>LINFNC</customer>
<newJob>Y</newJob>
<incrementJobVersion>Y</incrementJobVersion>
<description><![CDATA[409511]]></description>
<billPartsTogether>1</billPartsTogether>
<dateSetup><![CDATA[4/24/2013]]></dateSetup>
<promiseDate><![CDATA[4/24/2013]]></promiseDate>
<scheduledShipDate><![CDATA[4/24/2013]]></scheduledShipDate>
<adminStatus>O</adminStatus>
<shipVia>1</shipVia>
<jobType>5020</jobType>
<poNum><![CDATA[409511]]></poNum>
<itemTemplate><![CDATA[33503MN_0212]]></itemTemplate>
<JobParts>
<JobPart>
<jobPart>01</jobPart>
<contactNum/>
<description>409511_QTY-3_33503MN_0212</description>
<priority>1</priority>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[3]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[33503MN_0212]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>01</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
<JobPart>
<jobPart>02</jobPart>
<contactNum/>
<description>409511_QTY-1_AL-FSC-FST068_Z08</description>
<priority>1</priority>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[1]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[AL-FSC-FST068_Z08]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>02</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
<JobPart>
<jobPart>03</jobPart>
<contactNum/>
<description>409511_QTY-1_AN06819-AL3C_1012</description>
<priority>1</priority>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[1]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[AN06819-AL3C_1012]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>03</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
</JobParts>
</estimate>
以下是现在的XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" encoding="UTF-8" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:output cdata-section-elements="dateSetup promiseDate scheduledShipDate poNum qtyOrdered itemTemplate note"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/PODOrderSheet_Main">
<estimate>
<xsl:copy-of select="estimate[1]/customer"/>
<xsl:copy-of select="estimate[1]/newJob"/>
<xsl:copy-of select="estimate[1]/incrementJobVersion"/>
<xsl:copy-of select="estimate[1]/description"/>
<xsl:copy-of select="estimate[1]/billPartsTogether"/>
<xsl:copy-of select="estimate[1]/dateSetup"/>
<xsl:copy-of select="estimate[1]/promiseDate"/>
<xsl:copy-of select="estimate[1]/scheduledShipDate"/>
<xsl:copy-of select="estimate[1]/adminStatus"/>
<xsl:copy-of select="estimate[1]/shipVia"/>
<xsl:copy-of select="estimate[1]/jobType"/>
<xsl:copy-of select="estimate[1]/poNum"/>
<xsl:copy-of select="estimate[1]/itemTemplate"/>
<JobParts>
<xsl:apply-templates select="estimate/JobParts/JobPart"/>
</JobParts>
</estimate>
</xsl:template>
<xsl:template match="estimate/description">
<description>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="estimate/description"/>
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</description>
</xsl:template>
<xsl:template match="//estimate/JobParts/JobPart/description">
<description>
<xsl:value-of select="concat(//estimate/description,'_QTY-',//JobPart/qtyOrdered,'_',//JobPart/itemTemplate)"/>
</description>
</xsl:template>
<xsl:template match="jobPart">
<xsl:copy><xsl:number count="JobPart" level="any" format="01"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
非常感谢......
答案 0 :(得分:1)
我遇到的另一个问题是我需要手动将CDATA标识添加到元素中,并且无法将该元素添加到cdata-section-elements中的列表中,因为在文档中更深层嵌套了另一个具有相同名称的元素不需要CDATA指定的结构。
XML解析器是否使用CDATA部分表示特定位字符数据没有区别,<foo>something</foo>
与<foo><![CDATA[something]]></foo>
完全相同。实际上,使用disable-output-escaping手动添加cdata包装器 not 必然会产生正确的东西,因为序列化器没有意识到它输出的文本是在CDATA中并且无论如何都会用实体来转义它:如果您有description
元素,例如
<description><![CDATA[409 < 511]]></description>
然后尝试使用d-o-e CDATA标记将其复制到输出中将产生
<description><![CDATA[409 < 511]]></description>
最好不要打扰CDATA,只是让序列化程序以正常方式执行实体转义
<description>409 < 511</description>
(相当于原始元素)。
答案 1 :(得分:1)
样式表存在一些问题:
您使用estimate/description
包含xsl:copy-of
元素。因此,您只需获取元素的副本,并且永远不会应用与estimate/description
匹配的模板来转换它。
match
和select
属性中的位置路径可以是绝对或相对到上下文节点。绝对位置路径通常是样式表设计不佳的标志,并且很难从具有匹配路径的多个节点中选择一个。如您所发现的,通过获取集合中第一个节点的字符串值,将一组节点转换为字符串。而不是以某种方式使用position()
从集合中选择单个节点,最好使用相对局部路径。
您似乎不清楚使用 CDATA , PCDATA 和实体。这些只是表示XML文本节点中特殊字符的不同方式,而{em>含义,例如<![CDATA[use <> in Perl for reading]]>
和use <> in Perl for reading
相同。由于您只有两种表示相同文本字符串的替代方法,因此您不太可能特别想要一种或另一种,但您可能需要一个需要其XML数据的软件才能“正常”。
这种转变可以满足您的需求。我已将初始xsl:copy
列表更改为简单xsl:apply-templates
给第一个estimate
元素中没有子元素的子元素。这样,estimate/description
模板生效,并应用CDATA
标记。 JobPart/description
模板将复合描述字符串所需的三个值拉入三个XSL
变量,以使事情变得更整洁。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" encoding="UTF-8" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:output cdata-section-elements="dateSetup promiseDate scheduledShipDate poNum itemTemplate qtyOrdered note"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/PODOrderSheet_Main">
<estimate>
<xsl:apply-templates select="estimate[1]/*[not(*)]"/>
<JobParts>
<xsl:apply-templates select="estimate/JobParts/JobPart"/>
</JobParts>
</estimate>
</xsl:template>
<xsl:template match="estimate/description">
<description>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</description>
</xsl:template>
<xsl:template match="JobPart/description">
<xsl:variable name="estimate-description" select="ancestor::estimate/description"/>
<xsl:variable name="qty-ordered" select="parent::JobPart/qtyOrdered"/>
<xsl:variable name="item-template" select="parent::JobPart/itemTemplate"/>
<xsl:copy>
<xsl:value-of select="concat($estimate-description, '_QTY-', $qty-ordered, '_', $item-template)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="jobPart">
<xsl:copy><xsl:number count="JobPart" level="any" format="01"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<?xml version="1.0" encoding="UTF-8"?>
<estimate>
<customer>LINFNC</customer>
<newJob>Y</newJob>
<incrementJobVersion>Y</incrementJobVersion>
<description><![CDATA[409511]]></description>
<billPartsTogether>1</billPartsTogether>
<dateSetup><![CDATA[4/24/2013]]></dateSetup>
<promiseDate><![CDATA[4/24/2013]]></promiseDate>
<scheduledShipDate><![CDATA[4/24/2013]]></scheduledShipDate>
<adminStatus>O</adminStatus>
<shipVia>1</shipVia>
<jobType>5020</jobType>
<poNum><![CDATA[409511]]></poNum>
<itemTemplate><![CDATA[33503MN_0212]]></itemTemplate>
<JobParts>
<JobPart>
<jobPart>01</jobPart>
<contactNum/>
<description>409511_QTY-3_33503MN_0212</description>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[3]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[33503MN_0212]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>01</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
<JobPart>
<jobPart>02</jobPart>
<contactNum/>
<description>409511_QTY-1_AL-FSC-FST068_Z08</description>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[1]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[AL-FSC-FST068_Z08]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>02</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
<JobPart>
<jobPart>03</jobPart>
<contactNum/>
<description>409511_QTY-1_AN06819-AL3C_1012</description>
<productionStatus>O</productionStatus>
<qtyOrdered><![CDATA[1]]></qtyOrdered>
<shipToContact/>
<itemTemplate><![CDATA[AN06819-AL3C_1012]]></itemTemplate>
<JobNotes>
<JobNote>
<department>001</department>
<jobPart>03</jobPart>
<note><![CDATA[Rush Order]]></note>
</JobNote>
</JobNotes>
</JobPart>
</JobParts>
</estimate>