c# - 使用 XSLT 将 XML 转换为固定长度的文本文件

标签 c# .net xml xslt

我有一个 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>&#10;</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/

相关文章:

java - AdMob - 错误膨胀类 com.google.gms.AdView

适用于 Windows 和 Linux 的 c++ xml、tcp/ip 库

C# - 如何从路径中提取文件名和扩展名?

c# - Visual Studio Code - .NET Core 测试资源管理器

javascript - 检查页面中是否加载了每个 Ajax

java - 超出 post_max_size 时的 php 行为

c# - 如何将 System.Data.SQLite 合并到一个单一可执行程序中?

C# 3 维数组

c# - 用于自定义项目的 C DLL

java - spring-oxm:我可以解码文件的子元素吗?