首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CSV到XML hreflang站点地图

CSV到XML hreflang站点地图
EN

Stack Overflow用户
提问于 2020-07-29 19:53:35
回答 2查看 126关注 0票数 0

我对bash和脚本还不熟悉,所以希望得到一些帮助。

我正在尝试从csv输入生成一个XML文件,以最终形成一个18n XML站点地图

我的CSV的结构如下

iso语言列标题

恩,德,

恩-url,去-ulr,fr-url

en-url2 2,de-url2 2,fr-url2 2

我想将csv输出到XML站点地图格式中:

代码语言:javascript
复制
 <url>
<loc>http://www.example.com/english/page.html</loc>             #first column (second line)
<xhtml:link 
           rel="alternate"
           hreflang="de"                                        #second column iso value (first line)
           href="http://www.example.com/deutsch/page.html"/>    #second column URL (second line)
<xhtml:link 
           rel="alternate"
           hreflang="fr"                                       #third column iso value (first line)   
           href="http://www.example.com/french/page.html"/>    #third column URL (second line)  
 </url>

然后,这将遍历第一列中的所有值,以生成完整的sitemap。

我拼凑在一起的脚本并没有为我提供预期的输出,而且当我很难从数组中控制/回显值时,我变得有点卡住了。

我的脚本当前输出以下内容

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>en</loc> 
<xhtml:link rel="alternate" hreflang="en" href="fr"
<xhtml:link rel="alternate" hreflang="en" href="fr"
<xhtml:link rel="alternate" hreflang="en" href="fr"
  </url>
  <url>
    <loc>example.com</loc> 
<xhtml:link rel="alternate" hreflang="example.com" href="example.fr"
<xhtml:link rel="alternate" hreflang="example.com" href="example.fr"
<xhtml:link rel="alternate" hreflang="example.com" href="example.fr"
  </url>

我的剧本

代码语言:javascript
复制
`#!/bin/bash
file_in="sample.csv"
file_out="sample.xml"

echo '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xhtml="http://www.w3.org/1999/xhtml">' > $file_out
while IFS=$',' read -r -a arry
do
echo '  <url>' >> $file_out
echo '    <loc>'${arry[0]}'</loc> '>> $file_out
for u in "${arry[@]}"
do
echo '<xhtml:link rel="alternate" hreflang="'${arry[0]}'" href="'${arry[2]}'"'>> $file_out
done
echo '  </url>' >> $file_out
done < $file_in
echo '</urlset>' >> $file_out`

简而言之,脚本是从数组的索引中回显元素,而不是列。此外,需要从循环中转义hreflang值,以便它在输出的hreflang="“值中保持常量。

如果有人知道我如何将列存储为单独的数组,或者我如何在csv列中迭代过值,这将是非常有帮助的。

事先非常感谢!

EN

回答 2

Stack Overflow用户

发布于 2020-08-09 19:11:46

如果您想要创建一个XML文件,那么我肯定会使用正确的工具来完成这项工作。

因为Bash不懂XML,所以我推荐一个像西德尔这样的工具。

我假设'input.csv':

代码语言:javascript
复制
en,de,fr
http://www.example.com/english/page.html,http://www.example.com/deutsch/page.html,http://www.example.com/french/page.html

1.将csv文件转换为一系列“转置”序列

代码语言:javascript
复制
$ xidel -s input.csv -e 'x:lines($raw) ! array{tokenize(.,",")}'
["en", "de", "fr"]
["http://www.example.com/english/page.html", "http://www.example.com/deutsch/page.html", "http://www.example.com/french/page.html"]

$ xidel -s input.csv -e '
  let $ln:=x:lines($raw) ! array{tokenize(.,",")} return
  (1 to count($ln[1]())) ! join($ln(.))
'
en http://www.example.com/english/page.html
de http://www.example.com/deutsch/page.html
fr http://www.example.com/french/page.html

$ xidel -s input.csv -e '
  let $ln:=x:lines($raw) ! array{tokenize(.,",")} return
  (2 to count($ln[1]())) ! join($ln(.))
'
de http://www.example.com/deutsch/page.html
fr http://www.example.com/french/page.html

2.将这些序列转换为XML

代码语言:javascript
复制
xidel -s input.csv -e '
  let $ln:=x:lines($raw) ! array{tokenize(.,",")} return
  <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="https://www.w3.org/1999/xhtml">
    <url>
      <loc>{$ln[2](1)}</loc>
      {(2 to count($ln[1]())) ! <xhtml:link rel="alternate" hreflang="{$ln(.)[1]}" href="{$ln(.)[2]}"/>}
    </url>
  </urlset>
' --output-format=xml --output-node-indent --output-declaration='<?xml version="1.0" encoding="UTF-8"?>'
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="https://www.w3.org/1999/xhtml">
  <url>
    <loc>http://www.example.com/english/page.html</loc>
    <xhtml:link rel="alternate" hreflang="de" href="http://www.example.com/deutsch/page.html"/>
    <xhtml:link rel="alternate" hreflang="fr" href="http://www.example.com/french/page.html"/>
  </url>
</urlset>

(如果您的shell已经设置为UTF-8,那么--output-declaration是可选的)

票数 0
EN

Stack Overflow用户

发布于 2020-08-10 00:26:45

考虑一下对您的脚本所做的小更改。它将捕获数组中的列标题,以使处理更容易。

代码假定input.csv是

代码语言:javascript
复制
en,de,fr
en-url,de-ulr,fr-url
en-url2,de-url2,fr-url2

脚本(请参见下面关于重定向的说明)。

代码语言:javascript
复制
#!/bin/bash

# Redirect input and output
file_in="sample.csv"
file_out="sample.xml"
exec < $file_in >$file_out

# XML Header
echo '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xhtml="http://www.w3.org/1999/xhtml">'

# Read column headers into langs
IFS=$, read -r -a langs
# number of alternate languages
n_langs=${#langs[@]}

# Loop over data
# Read line of URLs
while IFS=$',' read -r -a urls
do
    echo "  <url>"
    echo "    <loc>${urls[0]}</loc> "
    # Loop of alternative languages
    for ((lx=1 ; lx<n_langs ; lx++)) ; do
        echo "    <xhtml:link rel="alternate" hreflang='${langs[lx]}' href='${urls[lx]}' />"
    done
    echo "  </url>"
done
echo "</urlset>"

备注:

  • 脚本对XML属性使用单引号。这就简单地引用了bash脚本。
  • 通常将脚本输入/输出参数化。不要硬编码输入和输出,考虑删除前3行(file_in=.),并使用重定向调用脚本:script.sh < sample.csv > sample.xml
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63161461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档