我有以下简化的XML结构:
<?xml version="1.0" encoding="UTF-8"?>
<ExportData>
<TransportHeader>
<Timestamp>2011-01-16 06:00:33</Timestamp>
<From>
<Name>DynamicExport</Name>
<Version>1.</Version>
</From>
<MessageId>d7b5c5b69a83</MessageId>
</TransportHeader>
<ExportConfig>
<DateTimeFormat>yyyy-MM-dd HH:mm:ss</DateTimeFormat>
<DecimalSymbol>.</DecimalSymbol>
</ExportConfig>
<DataSet>
<Tables>
<Table>
<RH>...</RH>
<Rows>
<R>Data1</R>
<R>Data2</R>
<R>Data3</R>
<R>Data4</R>
<R>Data5</R>
</Rows>
</Table>
</Tables>
</DataSet>
</ExportData>
Run Code Online (Sandbox Code Playgroud)
我必须检查<R>元素是否存在.如果不<R>存在元素,则必须中止映射,否则需要创建<Line>每个元素<R>.
我提出了迄今为止完美运行的解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output encoding="ISO-8859-1" method="xml" indent="yes" />
<!-- suppress nodes that are not matched -->
<xsl:template match="text() | @*">
<xsl:apply-templates select="text() | @*"/>
</xsl:template>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="not(ExportData/DataSet/Tables/Table/Rows/node())">
<xsl:message terminate="yes">No line items</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/ExportData/DataSet/Tables/Table/Rows">
<INVOIC02>
<!-- apply LINE ITEMS template -->
<xsl:apply-templates select="R"/>
</INVOIC02>
</xsl:template>
<!-- Template creating LINE ITEMS -->
<xsl:template match="R">
<Line>
<elements></elements>
</Line>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
如果有<R>元素输出是这样的:
<?xml version="1.0" encoding="ISO-8859-1"?>
<INVOIC02>
<Line>
<elements/>
</Line>
<Line>
<elements/>
</Line>
<Line>
<elements/>
</Line>
<Line>
<elements/>
</Line>
<Line>
<elements/>
</Line>
</INVOIC02>
Run Code Online (Sandbox Code Playgroud)
如果只有<Rows/>和没有<R>s映射被中止.
现在我有两个问题:
-is我测试<R>强大的元素:test="not(ExportData/DataSet/Tables/Table/Rows/node())"?
- 我<xsl:apply-templates>用来创建<Line>项目而不是<xsl:for-each>构造.我的XPath表达式是否正常还是可以让它们变得更好?
感谢您对此提出的任何回复或建议.
最好的问候,彼得
我对元素的测试是否健壮:test ="not(ExportData/DataSet/Tables/Table/Rows/node())"?
那么,如果没有R元素,你想要它失败吗?如果Rows没有孩子node(),你会想要失败吗,包括任何元素(不仅仅是R)text(),comment()或者processing-instruction()?
如果您确实要验证至少有一个R元素属于子元素,Rows则应将测试条件调整为更具体:
test="not(ExportData/DataSet/Tables/Table/Rows/R)"
Run Code Online (Sandbox Code Playgroud)
否则,它可能会通过该测试并继续处理,而不会生成您想要的内容.
Run Code Online (Sandbox Code Playgroud)I am using <xsl:apply-templates> to create the <Line> items instead of an <xsl:for-each> construct. Are my XPath expressions okay or could I make them better?
您可以删除<xsl:if>模板中用于根节点的条件逻辑,并将该逻辑移动到Rows不包含R子节点的模板中.将逻辑放入xsl:template @match标准可以使XSLT处理器更容易优化,从而提高性能.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output encoding="ISO-8859-1" method="xml" indent="yes" />
<!-- suppress nodes that are not matched -->
<xsl:template match="text() | @*">
<xsl:apply-templates select="text() | @*"/>
</xsl:template>
<!--All Rows must contain an R.
If we encounter any that do not, terminate the transform -->
<xsl:template match="/ExportData/DataSet/Tables/Table/Rows[not(R)]">
<xsl:message terminate="yes">No line items</xsl:message>
</xsl:template>
<!--match for Rows that have R children -->
<xsl:template match="/ExportData/DataSet/Tables/Table/Rows[R]">
<INVOIC02>
<!-- apply LINE ITEMS template -->
<xsl:apply-templates select="R"/>
</INVOIC02>
</xsl:template>
<!-- Template creating LINE ITEMS -->
<xsl:template match="R">
<Line>
<elements></elements>
</Line>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16051 次 |
| 最近记录: |