如何在不改变atribute值大小写的情况下将xml中所有标记中的标记转换为小写?
我继承了一些xml文件,其中所有标记都是大写的。我想使用正则表达式或通过XSLT将它们转换为小写。这将是方便的,能够知道这两种方式。不幸的是,我发现正则表达式和XSLT语法有时令人费解,但我正在研究它。:) (编辑:添加以下人为示例) 之前:如何在不改变atribute值大小写的情况下将xml中所有标记中的标记转换为小写?,xml,regex,xslt,Xml,Regex,Xslt,我继承了一些xml文件,其中所有标记都是大写的。我想使用正则表达式或通过XSLT将它们转换为小写。这将是方便的,能够知道这两种方式。不幸的是,我发现正则表达式和XSLT语法有时令人费解,但我正在研究它。:) (编辑:添加以下人为示例) 之前: <?xml version="1.0"?> <NOVEL TITLE="Now That's A Novel Title" AUTHOR="Harry Handelbar"> <PREFACE> <!-- X
<?xml version="1.0"?>
<NOVEL TITLE="Now That's A Novel Title" AUTHOR="Harry Handelbar">
<PREFACE> <!-- XHTML FORMATTED TEXT -->
<P>It would be remiss of me to neglect to thank the bottle.</P>
</PREFACE>
<CHAPTER TITLE="" TYPE="NUM">
<PROLOGUE>Success, like death, marks the end of... </PROLOGUE>
<MAINTEXT> <!-- XHTML FORMATTED TEXT -->
<P>It seems a violent betrayal, me divulging how...</P>
<P>The years had not been kind Felix Lake. His constant...</P>
</MAINTEXT>
</CHAPTER>
<CHAPTER TITLE="" TYPE="NUM">
<MAINTEXT> <!-- XHTML FORMATTED TEXT -->
<P>As luck would not have it, he did.</P>
<!-- ECT ECT ECT -->
</MAINTEXT>
</CHAPTER>
</NOVEL>
如果我忘了感谢这瓶酒,那将是我的失职。
成功就像死亡一样,标志着。。。
这似乎是一次暴力背叛,我透露了如何…
费利克斯湖的日子并不好过。他的常数…
由于运气不好,他成功了。
之后:
<?xml version="1.0"?>
<novel title="Now That's A Novel Title" author="Harry Handelbar">
<preface> <!-- XHTML FORMATTED TEXT -->
<p>It would be remiss of me to neglect to thank the bottle.</p>
</preface>
<chapter title="" type="NUM">
<prologue>Success, like death, marks the end of... </prologue>
<maintext> <!-- XHTML FORMATTED TEXT -->
<p>It seems a violent betrayal, me divulging how...</p>
<p>The years had not been kind Felix Lake. His constant...</p>
</maintext>
</chapter>
<chapter title="" type="NUM">
<maintext> <!-- XHTML FORMATTED TEXT -->
<p>As luck would not have it, he did.</p>
<!-- ECT ECT ECT -->
</maintext>
</chapter>
</novel>
如果我忘了感谢这瓶酒,那将是我的失职
成功就像死亡一样,标志着。。。
这似乎是一个暴力背叛,我透露如何
费利克斯湖的日子并不好过。他的恒量
幸运的是,他做到了
希望有帮助
编辑:p标签上的My bad-after也应为小写)尝试使用此正则表达式:
<(\/?[a-zA-Z]*)\b.*?>
在线测试仪:
享受你的代码通过使用PHP,你可以这样做
<?php
$pattern= '/<\\w+|<\/\\w+/';
$fp = fopen("/Applications/XAMPP/htdocs/test/test.xml", "r") or die("can't read stdin");
while (!feof($fp)) {
$line = fgets($fp);
$line = preg_replace_callback(
$pattern,
function ($matches) {
return strtolower($matches[0]);
},
$line
);
echo htmlentities($line);
}
fclose($fp);
?>
它工作得很好;) 尝试(未测试):
XSLT2.0:
<xsl:stylesheet version="2.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="*"/>
<xsl:template match="*">
<xsl:element name="{lower-case(local-name())}" namespace="{namespace-uri()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{lower-case(local-name())}" namespace="{namespace-uri()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="comment() | text() | processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
上述XSLT 1.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="*"/>
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:template match="*">
<xsl:element name="{translate(local-name(), $uppercase, $lowercase)}" namespace="{namespace-uri()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{translate(local-name(), $uppercase, $lowercase)}" namespace="{namespace-uri()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="comment() | text() | processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
但是,这是假设您的元素和属性名称不包含除明确列出的26个字符以外的大写字符(即不包含俄语、希腊语、变音符号等)。我认为您可能需要2个正则表达式-一个用于转换标记名,另一个用于转换可变数量的属性值对 以下是我如何做到的-
blah:tmp shreyas$ cat old.xml | perl -pe "s|(</?)([^> ]+)(.*?>)|\1\L\2\E\3|g" | perl -pe "s|(\w+)( ?= ?\".*?\")|\L\1\E\2|g" > processed.xml
blah:tmp shreyas$ diff new.xml processed.xml
4c4
< <P>It would be remiss of me to neglect to thank the bottle.</P>
---
> <p>It would be remiss of me to neglect to thank the bottle.</p>
9,10c9,10
< <P>It seems a violent betrayal, me divulging how...</P>
< <P>The years had not been kind Felix Lake. His constant...</P>
---
> <p>It seems a violent betrayal, me divulging how...</p>
> <p>The years had not been kind Felix Lake. His constant...</p>
15c15
< <P>As luck would not have it, he did.</P>
---
> <p>As luck would not have it, he did.</p>
blah:tmp shryas$cat old.xml | perl-pe“s |(]+)(.*?>)\1\L\2\E\3 | g“| perl-pe“s |”(\w+)(=?\“*?\”)\L\1\E\2 | g”>processed.xml
blah:tmp shryas$diff new.xml processed.xml
4c4
如果我不感谢这瓶酒,那将是我的失职。
---
>如果我忘了感谢这瓶酒,那将是我的失职
9,10c9,10
<这似乎是一次暴力背叛,我透露了如何…
<费利克斯湖的日子并不好过。他的常数…
---
>这似乎是一次暴力背叛,我透露了
>费利克斯湖的日子并不好过。他的恒量
15c15
由于运气不好,他成功了。
---
>由于运气不好,他成功了
old.xml是前xml,new.xml是后xml。processed.xml是由命令生成的
如您所见,after xml中的p标记仍然是大写的。我不确定它们是打字错误还是例外。自从你提到把所有标签改成小写后,我就把它们改成了打字错误
只需稍加修改,就可以在继承的所有XML集上运行这些命令,并快速转换它们 您可以发布一个示例XML和所需的输出吗?您可以使用XSLT 2.0吗?@michael.hor257k Yes to XSLT 2.0这看起来很有希望。不过,我似乎没有使用XSLT2.0。(收到“找不到函数:小写”消息。显然,Xalan(我已经使用多年)是XSLT 1.0处理器。我可能会考虑另一种选择。我也使用Apache FOP,所以我希望找到与之兼容的东西。有什么建议吗?@HarryHB是的,没有小写()XSLT 1.0中的函数。这就是为什么备选方案很笨重(请参见上面的编辑)。这就是为什么我首先问的问题…一流!XSLT 1.0版本做得很好。是的,很抱歉版本混淆。我一直在错误的假设下工作。26个大写字符对我来说就足够了。:)大写的P标记是我的错(现已编辑完毕)-幸运的是,我的电脑上有cygwin,所以我可以尝试你的方法。虽然它确实保留了属性名称的大写字母,但效果很好。你能建议一个mod@HarryHB如果你正在运行这个命令-cat old.xml | perl-pe“s |(]+)(.*>)|\1\L\2\E\3 | g“| perl-pe“s |(\w+(=?*?)”))\L\1\E\2 | g”>processed.xml-完整地说,您不应该有任何大写的属性名称。如果您有,请在xml中共享该完整节点。