将XSLT应用于XML中特定于大小写的元素

将XSLT应用于XML中特定于大小写的元素,xml,xslt,Xml,Xslt,我正在尝试使用XSLT来处理三个XML元素,只是没有将如何将XSLT模板应用于特定元素的要点联系起来 以下是XML的一个示例: <?xml version="1.0" encoding="us-ascii"?> <jsi:CitationCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:j="http://niem.gov/niem/domains/jxdm/4.0" xmlns:nc=

我正在尝试使用XSLT来处理三个XML元素,只是没有将如何将XSLT模板应用于特定元素的要点联系起来

以下是XML的一个示例:

<?xml version="1.0" encoding="us-ascii"?>
<jsi:CitationCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:j="http://niem.gov/niem/domains/jxdm/4.0" xmlns:nc="http://niem.gov/niem/niem-core/2.0" xmlns:s="http://niem.gov/niem/structures/2.0" xmlns:jsi="http://www.justicesystems.com/iepd" xsi:schemaLocation="http://www.justicesystems.com/iepd extension-schema.xsd">
  <jsi:CitationDocument>
    <nc:Person>
        <nc:PersonName>
            <nc:PersonGivenName>FIRST NAME</nc:PersonGivenName>
            <nc:PersonMiddleName>MIDDLE NAME</nc:PersonMiddleName>
            <nc:PersonSurName>LAST NAME</nc:PersonSurName>
          </nc:PersonName>
    </nc:Person>
  </jsi:CitationDocument>
</jsi:CitationCollection>  

名字
中名
姓
以下是我当前的XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="CamelCase">
  <xsl:param name="text"/>
  <xsl:choose>
    <xsl:when test="contains($text,' ')">
      <xsl:call-template name="CamelCaseWord">
        <xsl:with-param name="text" select="substring-before($text,' ')"/>
      </xsl:call-template>
      <xsl:text> </xsl:text>
      <xsl:call-template name="CamelCase">
        <xsl:with-param name="text" select="substring-after($text,' ')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="CamelCaseWord">
        <xsl:with-param name="text" select="$text"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="CamelCaseWord">
  <xsl:param name="text"/>
  <xsl:value-of select="translate(substring($text,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" /><xsl:value-of select="translate(substring($text,2,string-length($text)-1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')" />
</xsl:template>

</xsl:stylesheet>

以下是我想要的:

<jsi:CitationCollection>
  <jsi:CitationDocument>
    <nc:Person>
        <nc:PersonName>
            <nc:PersonGivenName>First Name</nc:PersonGivenName>
            <nc:PersonMiddleName>Middle Name</nc:PersonMiddleName>
            <nc:PersonSurName>Last Name</nc:PersonSurName>
          </nc:PersonName>
    </nc:Person>
  </jsi:CitationDocument>
</jsi:CitationCollection> 

名字
中名
姓

非常感谢您的帮助。

我建议您这样做:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="text()" name="capitalize-words">
    <xsl:param name="text" select="."/>
    <xsl:variable name="uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
    <xsl:variable name="lowercase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
    <xsl:variable name="word" select="substring-before(concat($text, ' '), ' ')" />
    <xsl:value-of select="translate(substring($word, 1, 1), $lowercase, $uppercase)" />
    <xsl:value-of select="translate(substring($word, 2), $uppercase, $lowercase)" />
    <xsl:if test="contains($text, ' ')">
        <xsl:text> </xsl:text>
        <!-- recursive call -->
        <xsl:call-template name="capitalize-words">
            <xsl:with-param name="text" select="substring-after($text, ' ')"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz


请注意,这会适得其反,比如
Anne Nicole
d'Angelo
MacNamara

我建议您这样尝试:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="text()" name="capitalize-words">
    <xsl:param name="text" select="."/>
    <xsl:variable name="uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
    <xsl:variable name="lowercase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
    <xsl:variable name="word" select="substring-before(concat($text, ' '), ' ')" />
    <xsl:value-of select="translate(substring($word, 1, 1), $lowercase, $uppercase)" />
    <xsl:value-of select="translate(substring($word, 2), $uppercase, $lowercase)" />
    <xsl:if test="contains($text, ' ')">
        <xsl:text> </xsl:text>
        <!-- recursive call -->
        <xsl:call-template name="capitalize-words">
            <xsl:with-param name="text" select="substring-after($text, ' ')"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz


请注意,这将适得其反,例如
Anne Nicole
d'Angelo
MacNamara

,您可以在文本节点上将模板与

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="CamelCase" match="text()[normalize-space()]">
    <xsl:param name="text" select="."/>
    <xsl:choose>
        <xsl:when test="contains($text, ' ')">
            <xsl:call-template name="CamelCaseWord">
                <xsl:with-param name="text" select="substring-before($text, ' ')"/>
            </xsl:call-template>
            <xsl:text> </xsl:text>
            <xsl:call-template name="CamelCase">
                <xsl:with-param name="text" select="substring-after($text, ' ')"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="CamelCaseWord">
                <xsl:with-param name="text" select="$text"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="CamelCaseWord">
    <xsl:param name="text"/>
    <xsl:value-of
        select="translate(substring($text, 1, 1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    <xsl:value-of
        select="translate(substring($text, 2), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"
    />
</xsl:template>

您可以将文本节点上的模板与

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="CamelCase" match="text()[normalize-space()]">
    <xsl:param name="text" select="."/>
    <xsl:choose>
        <xsl:when test="contains($text, ' ')">
            <xsl:call-template name="CamelCaseWord">
                <xsl:with-param name="text" select="substring-before($text, ' ')"/>
            </xsl:call-template>
            <xsl:text> </xsl:text>
            <xsl:call-template name="CamelCase">
                <xsl:with-param name="text" select="substring-after($text, ' ')"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="CamelCaseWord">
                <xsl:with-param name="text" select="$text"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="CamelCaseWord">
    <xsl:param name="text"/>
    <xsl:value-of
        select="translate(substring($text, 1, 1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    <xsl:value-of
        select="translate(substring($text, 2), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"
    />
</xsl:template>



“如何将XSLT模板应用于特定元素”?具体的要素是什么?将它们与模板匹配,例如,
。不清楚您在这里到底想要实现什么。转换给定示例的预期结果是什么?好的,我添加了我想要的@迈克尔。霍尔257K这不是骆驼案;那只是(每个单词?)的第一个字母大写另外,请将您的输入修改为格式良好的XML;你可以;如果没有将前缀绑定到名称空间,则不能使用前缀。好的,调整示例更多。。。只要每个单词的第一个字母大写就足够@michael.hor257k“如何将XSLT模板应用于特定元素”?具体的要素是什么?将它们与模板匹配,例如,
。不清楚您在这里到底想要实现什么。转换给定示例的预期结果是什么?好的,我添加了我想要的@迈克尔。霍尔257K这不是骆驼案;那只是(每个单词?)的第一个字母大写另外,请将您的输入修改为格式良好的XML;你可以;如果没有将前缀绑定到名称空间,则不能使用前缀。好的,调整示例更多。。。只要大写每个单词的第一个字母就足够了@michael.hor257kOk cool,谢谢。我同意d'Angelo和MacNamara的观点,你能建议一种更为稳健的替代方法吗?此外,为了简洁起见,我删去了XML中存在的许多其他元素,我认为我可以通过您所拥有的来实现我想要的。我认为我不想将此应用于所有文本元素,如果我读对了这一点,它就是这样做的。您可以添加一个与要大写的元素匹配的模板,并从中按名称调用大写模板(删除
匹配-“text()”
部分)我不知道有什么方法可以让它真正“健壮”;您可以添加更多分隔符,但您需要人类智能来区分MacNamara和Macintosh。没有办法分辨麦克唐纳到底是麦克唐纳还是麦克唐纳。我同意,这很危险。我会胡思乱想,找出如何将它应用到某些元素上,我很感激你能帮我摆脱困境。我不确定你的用例是什么,但我通常建议类似情况下的客户离我远点。人们对自己的名字拼写错误很敏感。我听说我的使用案例是我们将这个XML导入到一个系统中,然后人们逐个检查每个记录和正确的大小写名称。这至少让他们离最终目标更近了一点。好的,很酷,谢谢。我同意d'Angelo和MacNamara的观点,你能建议一种更为稳健的替代方法吗?此外,为了简洁起见,我删去了XML中存在的许多其他元素,我认为我可以通过您所拥有的来实现我想要的。我认为我不想将此应用于所有文本元素,如果我读对了这一点,它就是这样做的。您可以添加一个与要大写的元素匹配的模板,并从中按名称调用大写模板(删除
匹配-“text()”
部分)我不知道有什么方法可以让它真正“健壮”;您可以添加更多分隔符,但您需要人类智能来区分MacNamara和Macintosh。没有办法分辨麦克唐纳到底是麦克唐纳还是麦克唐纳。我同意,这很危险。我会胡思乱想,找出如何将它应用到某些元素上,我很感激你能帮我摆脱困境。我不确定你的用例是什么,但我通常建议类似情况下的客户离我远点。人们对自己的名字拼写错误很敏感。我听说我的使用案例是我们将这个XML导入到一个系统中,然后人们逐个检查每个记录和正确的大小写名称。这至少让他们更接近最终目标。