我有一个 XML,需要将其转换为固定宽度样式的文本文件,并且必须使用 XSLT 方法来完成此操作。
我是第一次使用 XSLT,我已经了解了基础知识,但是这个源 XML 的某些方面使它变得困难......至少对我来说是这样。
<Prescription>
<Drugs>
<Drug id="1">
<DrugName>Red Tablets</DrugName>
</Drug>
<Drug id="2">
<DrugName>Blue Tablets</DrugName>
</Drug>
</Drugs>
<Patients>
<Patient id="20">
<Surname>Doe</Surname>
<Forenames>John</Forenames>
<Items>
<Item>
<ProductID>1</ProductID>
<AdminEvent date="2016-05-11" hour="7" qty="1"/>
<AdminEvent date="2016-05-12" hour="7" qty="1"/>
</Item>
</Items>
</Patient>
<Patient id="50">
<Surname>Doe</Surname>
<Forenames>Jane</Forenames>
<Items>
<Item>
<ProductID>2</ProductID>
<AdminEvent date="2016-05-11" hour="7" qty="1"/>
<AdminEvent date="2016-05-12" hour="7" qty="1"/>
</Item>
</Items>
</Patient>
<Patients>
这是一张包含 2 种药物和两名患者的处方。患者约翰在早上 7 点服用红色药片 2 天,简则服用蓝色药片。我需要将其放入纯文本文件中,例如:
[ForeName]+[Surname]+[DrugName]+[DrugID]+[Hour]+[Qty]+[Date]
所以在这个例子中:
John Doe Blue Tablets 1 7 1 2016-05-11
John Doe Blue Tablets 1 7 1 2016-05-12
Jane Doe Red Tablets 2 7 1 2016-05-11
Jane Doe Red Tablets 2 7 1 2016-05-12
我对以下概念感到困惑: a) 引用不同的分支(EG 从 Item 元素回溯到 Drug) b) 仅获取 Item 部分中 ID 的 DrugName
希望这一切都是有意义的!
最佳答案
XSLT 1.0
此转换将动态调整患者和药物名称的字段长度...如果它们是固定的,您可以进一步简化。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
>
<xsl:output method="text" indent="yes"/>
<xsl:variable name="name-max-length">
<xsl:for-each select="//Patient">
<xsl:sort select="string-length(concat(Forenames,' ',Surname))" data-type="number" />
<xsl:if test="position() = last()">
<xsl:value-of select="string-length(concat(Forenames,' ',Surname))" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="drug-max-length">
<xsl:for-each select="//DrugName">
<xsl:sort select="string-length(.)" data-type="number" />
<xsl:if test="position() = last()">
<xsl:value-of select="string-length(.)" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="//AdminEvent"/>
</xsl:template>
<xsl:template match="AdminEvent">
<xsl:variable name="name" select="concat(ancestor::Patient/Forenames,' ',ancestor::Patient/Surname)" />
<xsl:variable name="productId" select="ancestor::Item/ProductID/text()"/>
<xsl:variable name="drug" select="ancestor::Prescription/Drugs/Drug[@id=$productId]/DrugName"/>
<xsl:value-of select="substring(concat($name,' '),1,($name-max-length + 4))"/>
<xsl:value-of select="substring(concat($drug,' '),1,($drug-max-length + 4))"/>
<xsl:value-of select="substring(concat($productId,' '),1,5)"/>
<xsl:value-of select="substring(concat(@hour,' '),1,5)"/>
<xsl:value-of select="substring(concat(@qty,' '),1,5)"/>
<xsl:value-of select="substring(concat(@date,' '),1,10)"/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
结果
John Doe Red Tablets 1 7 1 2016-05-11
John Doe Red Tablets 1 7 1 2016-05-12
Jane Doe Blue Tablets 2 7 1 2016-05-11
Jane Doe Blue Tablets 2 7 1 2016-05-12
关于c# - 使用 XSLT 将 XML 转换为固定长度的文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37324433/